さくらインターネットで Movable Type のダイナミックパブリッシングによる500エラーを確実に解消する方法
さくらインターネットで Movable Type のダイナミックパブリッシングによる500エラーを解消する方法をまとめましたので、本エントリーにて情報展開致します。
さくらインターネット+ダイナミックパブリッシング+500エラーの解消方法は、色々なサイトで公開されているのですが、サイトパスの設定によって500エラーが解消されないケースがあったため、改めて調査を行い、どのような設定を行なっても確実に500エラー解消する方法を網羅しました。
また、他のサイトでは500エラーを解消するための対処方法として冗長な情報も紛れ込んでいると思われるため、本エントリーでは正常に動作させるための最小限の方法のみ紹介し、それ以外の変更の要否については、5項にFAQとしてまとめてみました。認識誤りがありましたらご指摘ください。
動作を確認したプランは、さくらインターネット「レンタルサーバ」の「スタンダード」プランおよび「マネージドサーバ」です。Movable Typeのバージョンは5.02で確認しましたが、MT4.xでも同様の対処で解消すると思われます。
1.問題点
さくらインターネットのスタンダードプランやプレミアムプランを利用している場合、ダイナミックパブリッシングを設定し、設定後にダイナミックパブリッシング対象のページにアクセスすると、次のような500エラーが発生します。

2.原因と対処(その1:.htaccessの修正)
1つの原因は、多くのサイトで言及されていますが、ダイナミックパブリッシングを設定した際に生成される .htaccess というファイルの中にある4行目のOptionsディレクティブ(赤色部分)がさくらインターネットでサポートされていないためです。
## %%%%%%% Movable Type generated this part; don't remove this line! %%%%%%%
# Disable fancy indexes, so mtview.php gets a chance...
Options -Indexes +SymLinksIfOwnerMatch
<IfModule mod_rewrite.c>
…後略…
エラーログを確認すると、次のような1行が表示されているので、このことより上記の原因であることが分かります。
/home/xxx/www/mt/.htaccess: Options not allowed here
対処方法は、FFFTPなどのFTPツールで、このファイルをローカルPCにダウンロードして、任意のエディタで開き、この1行を削除する(対処1-1)か、あるいはOptionsディレクティブの行頭に半角の「#」をつけてコメントアウトします(対処1-2)。編集後、同じディレクトリにアップロードしてください。
対処1-1
## %%%%%%% Movable Type generated this part; don't remove this line! %%%%%%%
# Disable fancy indexes, so mtview.php gets a chance...
<IfModule mod_rewrite.c>
…後略…
対処1-2
## %%%%%%% Movable Type generated this part; don't remove this line! %%%%%%%
# Disable fancy indexes, so mtview.php gets a chance...
#Options -Indexes +SymLinksIfOwnerMatch
<IfModule mod_rewrite.c>
…後略…
編集後、同じディレクトリにアップロードしてください。この対処方法は公式ドキュメントでも公開されています。
余談ですが、エラーログを参照する設定は、サーバコントロールパネルより、「アクセスログの設定」をクリックします。

そして、「アクセスログの保存設定」から「残す」を選択して、「エラーログも残す」をチェックします。

3.原因と対処(その2:ディレクトリのパーミッション修正)
2項の対処だけを行なっても500エラーが解消しない場合、もうひとつの原因は、ウェブサイトやブログのサイトパスとなるディレクトリのパーミッションです。
MTの管理画面でウェブサイトやブログのサイトパスを作成すると、そのディレクトリのパーミッションは「777」になります。さくらインターネットではsuexecを採用しており、「777」というパーミッションではother(1桁目)にwriteパーミッションがあるため、500エラーとなります。
エラーログを確認すると、次のような1行が表示されており、上記が原因であることが推測されます。
suexec policy violation: see suexec log for more details
suexecのログは確認していませんが、ネットで検索すると次の記事がありました。
対処方法は、ダイナミックパブリッシングを適用しているウェブサイトまたはブログの一番最後のサイトパスのパーミッションを「705」に変更します。
念のため、FFFTPを利用したパーミッションの変更方法を以下に掲載しておきます。
変更対象となるサイトパスの一番下位のディレクトリを右クリックして、「属性変更」を選択します。例えばサイトパスが /home/[ユーザ名]/www/foo となっている場合、fooディレクトリを選択します。

開いたダイアログで、ディレクトリのパーミッションを「705」に変更します。「755」でも問題ありません。

パーミッションを変更するディレクトリはこの部分のみです。それより上位のディレクトリのパーミッションを変更する必要はありません。また、/home/[ユーザ名]/www 直下をウェブサイトやブログのサイトパスにする場合、wwwのパーミッションが755になっていればこの作業は不要です。
また、ネット上でのsuexecの情報で「701」の設定が推奨されている場合もありますが、その設定ではスタイルシートファイルなどが参照できなくなったため、少なくともotherにリード権のある705に変更してください。
4.ダイナミックパブリッシングを利用するパスが複数ある場合
ウェブサイトとブログ、あるいは複数のブログでそれぞれダイナミックパブリッシングを行なっている場合は、2項と3項の対処についてそれぞれ実施してください。具体的には次の通りです。
- ウェブサイトのサイトパスにある.htaccessを修正し、ウェブサイトのサイトパスのパーミッションを変更
- 各ブログのサイトパスにある.htaccessを修正し、ブログのサイトパスのパーミッションを変更
またブログで、アーカイブをブログパスと別のパスで公開している場合も、アーカイブパスのディレクトリについて、2項と3項の対処を行なってください。
5.FAQ
ネット上でみつけた他の対処方法についての要/不要について、この項で見解を述べておきます。理解が間違っていたらご指摘ください。
Q:mtview.phpのパーミッションを変更する必要はありますか?
A:パーミッションを変更する必要はありません。705/755に変更してください。
ダイナミックパブリッシングを設定すると、サイトパス上にmtview.phpというファイルが生成されます。このファイルのパーミッションは644で生成され、「CGIと動作させるために755や705に変更してください」という情報がありましたが、す。特に変更する必要はありません。もしCGIとして動作させるために変更が必要なのであれば、MTのインストールディレクトリに含まれるPHPファイルのパーミッションをすべて変更しなければならなくなります。てください。
なお、mtview.phpおよびPHPファイルのパーミッションが644でも正常に動作することを確認しています。
いずれの場合も、mtview.phpが属するディレクトリのパーミッションも705/755に変更してください。777など、「グループ」「その他」のクラスに書き込み権があるパーミッションでは500エラーが発生します。
Q:templates_cやcacheというディレクトリのパーミッションの変更は必要ですか?
A:パーミッションを変更する必要はありません。
ダイナミックパブリッシングを設定すると、サイトパス上にtemplates_cというディレクトリが生成されます。また、キャッシュの利用を有効にすると、さらにcacheというディレクトリが生成されますが、これらのパーミッションは変更せずに表示されることを確認しています。
Q:ファイルの拡張子を.htmlから.phpに変更する必要はありますか?
A:拡張子を変更する必要はありません。
ダイナミックパブリッシングは.htaccessで制御し、通常の.htmlファイルをPHPとして動作させるため、拡張子を変更する必要はありません。
注:これらの見解について、Movable Type の環境変数はすべてデフォルトの状態で動作確認を行なっています。UploadPermsやUploadUmaskなど、環境変数の設定状況によってはこの限りでないかもしれません。
6.モジュール版での設定
これまでに説明した設定は、CGI版(PHPをCGIをして動作させる場合)での話です。
さくらインターネットでは、レンタルサーバの上位サービスの「ビジネスプロ」やマネージドサーバであれば、PHPの「モジュールモード(モジュール版)」が用意されています。このモードを利用する場合、2項の設定のみ行い、3項の設定は行なわなくても正常に動作するようです。
CGI版とモジュール版の違いについては以下の記事を参照してください。
7.「キャッシュ」または「条件付き取得」の併用
ダイナミックパブリッシングを利用する場合、サーバの負荷を軽減するために、「キャッシュ」または「条件付き取得」の併用を推奨します。
設定方法は、ダイナミックパブリッシングを設定したあと、「設定」→「全般」をクリックし、次の画面で「キャッシュする」または「条件付き取得を有効にする」をチェックします。

キャッシュをすることで、前回のアクセスから変更されていないページはキャッシュを利用します。条件付き取得は、HTTP 304応答を行ないます。詳細は下記のページを参照してください。
8.その他
スタティックパブリッシングからダイナミックパブリッシングに移行した場合、スタティックパブリッシングの設定時にすでに出力されていたページは、「.static」という拡張子をつけてリネームされます。
実験では、このファイルが残っていれば、3項の対処を行なわなくてもアクセスが可能な場合がありましたが(理由は不明)、ダイナミックパブリッシング設定後のブログ記事などは500エラーとなるので、必ず3項の対処を実施してください。
なお、「.static」という拡張子がついたファイルは再利用されることはありませんので、ディスクの容量削減のため、削除することを推奨します。
2010.09.01
FAQの記述を修正しました。
MT::FileInfoについて
昨日の「ダイナミックパブリッシングでURLが重複する事象について」の続きで、ダイナミックパブリッシングの設定方法の違いによるMT::FileInfoの状態などを簡単に調べてみました。
1.前準備
ブログ記事は次のものが投稿済みです。
- モバイルサイトオープン
- 業務提携に関するお知らせ
- ソリューションセミナー
- Movable Type 入門セミナー
- オフィシャルサイトオープン
- Movable Type 4 へようこそ!
- シンポジウム2010
- ホームページリニューアル
この状態で、phpMyAdminを使って、MT::FileInfo(mt_fileinfoテーブル)のオブジェクトデータを削除しておきます。
2.インデックステンプレートを個別にダイナミックパブリッシングにする
次のサブテンプレートを記述した、ダイナミックパブリッシングのインデックステンプレートを作成します。
<mt:Entries>
<mt:EntriesHeader>
<ul>
</mt:EntriesHeader>
<li><a href="<mt:EntryPermalink />"><mt:EntryTitle /></a></li>
<mt:EntriesFooter>
</ul>
</mt:EntriesFooter>
</mt:Entries>
このインデックステンプレートで作成したページにアクセスすると、ソースコードは次のようになりました。MTEntryTitleタグは評価されていますが、MTEntryPermalinkタグがまったく評価されていないことが分かります。
<ul>
<li><a href="">モバイルサイトオープン</a></li>
<li><a href="">業務提携に関するお知らせ</a></li>
<li><a href="">ソリューションセミナー</a></li>
<li><a href="">Movable Type 入門セミナー</a></li>
<li><a href="">オフィシャルサイトオープン</a></li>
<li><a href="">Movable Type 4 へようこそ!</a></li>
<li><a href="">シンポジウム2010</a></li>
<li><a href="">ホームページリニューアル</a></li>
</ul>
そしてmt_fileinfoテーブルには、このインデックステンプレートのオブジェクトデータが1件追加されます。このデータはテンプレートの保存時に追加されます。

3.公開プロファイルでダイナミックパブリッシングを選択する
次に、公開プロファイルでダイナミックダイナミックパブリッシングを選択してみます。

この後、選択したプロファイルを実行すると、「ダイナミックリンクを再構築中」という聞きなれない単語が表示されます。

完了後、mt_fileinfoテーブルを参照すると、すべてのページに対するオブジェクトデータが生成されていることが分かります。つまり「ダイナミックリンク」とは、mt_fileinfoテーブルへのオブジェクトデータ追加、つまりダイナミックパブリッシングで生成したページにアクセスできる状態を指すようです。

この状態で2項のページにアクセスすると、冒頭のMTEntryPermalinkタグも評価されました。
<ul>
<li><a href="http://user-domain/2010/09/post-9.html">モバイルサイトオープン</a></li>
<li><a href="http://user-domain/2010/08/post-8.html">業務提携に関するお知らせ</a></li>
<li><a href="http://user-domain/2010/07/java.html">ソリューションセミナー</a></li>
<li><a href="http://user-domain/2010/06/movable-type.html">Movable Type 入門セミナー</a></li>
<li><a href="http://user-domain/2010/05/post-1.html">オフィシャルサイトオープン</a></li>
<li><a href="http://user-domain/2010/05/movable-type-4.html">Movable Type 4 へようこそ!</a></li>
<li><a href="http://user-domain/2010/04/2010.html">シンポジウム2010</a></li>
<li><a href="http://user-domain/2010/03/post.html">ホームページリニューアル</a></li>
</ul>
4.mt_fileinfoテーブルのオブジェクトデータがない場合
ちなみに、再度mt_fileinfoテーブルのオブジェクトデータをすべて削除して、2項のページにアクセスすると、次のようなエラーになりました。
![]()
5.まとめ
ページアクセス時の動作は次のとおりです。
- MT::FileInfoオブジェクトあり:オブジェクトに対応するページは表示される(2項)。ただしMT::FileInfoオブジェクトの生成状態によっては正常に評価されないテンプレートタグあり。
- MT::FileInfoオブジェクトなし:ダイナミックパブリッシングエラー(4項)
また、ダイナミックパブリッシングの設定方法によるMT::FileInfoオブジェクトの生成範囲は次の通りです。
- 個別にダイナミックパブリッシングを設定:該当のテンプレートから生成されるページのMT::FileInfoオブジェクトを生成(2項)
- 公開プロファイルで設定:すべてのページのMT::FileInfoオブジェクトを生成(3項)
ダイナミックパブリッシングでURLが重複する事象について
「Movable Type 5 プロフェッショナルガイド」を執筆している最中に気がついたのですが、ツールのインポート機能を利用して、インポートしたブログ記事をダイナミックパブリッシングで表示すると、期待通りの出力にならないという事象が発生しました。
1.問題
具体的には、MTEntryPermalinkタグやMTArchiveLinkタグの出力が、他のブログ記事やアーカイブページのURLと重複するという事象になりました。
2.原因
ダイナミックパブリッシング設定後、テンプレートの再構築を行っていなかったためと思われます。なお、ダイナミックパブリッシングの設定は「公開プロファイル」ではなく、特定のインデックステンプレートだけに適用しました。
3.対処
テンプレートの再構築を行うことで適正なURLが出力されるようになりました。インポートしたデータをダイナミックパブリッシングで適正な内容を表示するには、一旦各テンプレートの再構築を行わないといけないようです。
以下推測です(認識誤りでしたらご指摘ください)が、ダイナミックパブリッシングでは、FileInfoという、URLとファイルをマッピングするテーブルが利用されます。今回の事象では、このテーブルが生成されていなかったのが原因かもしれません。
月別アーカイブリストの年別表示(ダイナミックパブリッシング対応:年・月を昇順に表示)
Movable Type の「月別アーカイブリスト」のダイナミックパブリッシング対応版です。
「月別アーカイブリストの年別表示(ダイナミックパブリッシング対応)」では、年・月を降順に表示するパターンしか掲載していませんでしたが、今回は昇順に表示するパターンも作りました。

デフォルトテンプレート用の「月別アーカイブリスト」は次の通りです。
<mt:ifArchiveTypeEnabled archive_type="Monthly">
<mt:ArchiveList archive_type="Monthly" sort_order="ascend">
<mt:ArchiveListHeader>
<div class="widget-archive-monthly widget-archive widget">
<h3 class="widget-header"><$mt:ArchiveTypeLabel$> <a href="<$mt:Link template="archive_index"$>">アーカイブ</a></h3>
<div class="widget-content">
<ul>
<li><mt:ArchiveDate format="%Y年" />
<ul>
</mt:ArchiveListHeader>
<mt:ArchiveDate format="%Y年" setvar="current_year" />
<mt:if tag="ArchivePrevious">
<mt:ArchivePrevious><mt:ArchiveDate format="%Y年" setvar="prev_year" /></mt:ArchivePrevious>
</mt:if>
<mt:if name="prev_year">
<mt:if name="current_year" ne="$prev_year">
</ul>
</li>
<li><mt:GetVar name="current_year" />
<ul>
</mt:if>
</mt:if>
<li><a href="<$mt:ArchiveLink$>"><$mt:ArchiveTitle regex_replace="/\d+年/",""$> (<$mt:ArchiveCount$>)</a></li>
<mt:ArchiveListFooter>
</ul>
</li>
</ul>
</div>
</div>
</mt:ArchiveListFooter>
</mt:ArchiveList>
</mt:ifArchiveTypeEnabled>
Ajax ダイナミック月送りカレンダー
Movable Type 4 以降のバージョンで、ブログ記事が投稿されていない月のカレンダーも含めて月送りができるカレンダーです。リアルタイムカレンダー(本日の日付の装飾)および土・日・休日表示も盛り込まれています。

このカスタマイズは下記のサイトで紹介されています。これまで月送りカレンダーのカスタマイズは色々行なってきましたが、ブログ記事が投稿されていない月のカレンダーの表示方法が思いつきませんでした。このアイデアは素晴らしいと思います。
1.概要
Ajax ダイナミック月送りカレンダーの動作概要を図に示します(図をクリックすれば拡大します)。
①:ページを表示します
②:ページに埋め込んだスクリプトで Ajax 呼び出しを行ないます
③:Ajax から呼び出すページ(カレンダー)をダイナミックパブリッシングで起動します
④:ページを呼び出す際に、年月データをクエリーとして与え、プラグインで取得し、テンプレーとに引継ぎます
⑤:取得した年月データを MTCalendar タグの month モディファイアの値として利用し、該当月のカレンダーを生成します
⑥⑦:生成したデータを返却し、最初のページに表示します。表示されたカレンダーの前月・次月のリンクにも同じ仕組みを適用します。前月・次月の算出は、MTArchive 系テンプレートタグではなく、制御系テンプレートタグで計算します。
このような構造にすることで、ブログ記事がない月のカレンダーを含めた月送りが実現できます。
なお、上記の説明でお分かりの通り、このカスタマイズはダイナミックパブリッシングの利用が可能な環境に限ります。
以下、カスタマイズ方法です。
2.スクリプトのダウンロード・アップロード
下記のスクリプトをダウンロードします。
prototype.js("Download the latest version" のリンクをクリック)ajaxCalendar.jsdayChecker.js(「2.ダウンロード」にある dayChecker.js をクリック)
ダウンロードした ajaxCalendar.js と dayChecker.js はメインページと同じディレクトリにアップロードしてください。
また prototype.js も、ダウンロードしたスクリプトをメインページと同じディレクトリにアップロードしてください。
3.プラグインのダウンロード・アップロード
下記のリンクをクリックして、GetQueryString プラグインをダウンロードします。このプラグインは、ダイナミックパブリッシングでカレンダーページを呼び出すときにクエリーを取得するためのものです。
ダウンロードしたアーカイブを展開し、中にある GetQueryString フォルダを plugins ディレクトリにアップロードします。
アップロード後、システム管理画面の「ツール」→「プラグイン」で GetQueryString が表示されていればOKです。

4.日別アーカイブの追加
この設定は、カレンダーに表示された日付のリンク先のページとして日別アーカイブを生成するためのものです。
「デザイン」→「テンプレート」→「アーカイブテンプレート」→「ブログ記事リスト」を選択。

アーカイブマッピングの「新しいアーカイブマッピングを作成」をクリック。

「日別」を選択して「追加」をクリック。

これで日別アーカイブが追加されました。

再構築アイコンをクリックして、日別アーカイブページを生成してください。
5.カレンダーテンプレート作成
管理メニューの「デザイン」→「テンプレート」→「インデックステンプレート」→「インデックステンプレートを作成」をクリック。

次画面で下記を設定してください。
- テンプレート名(一番上のテキストフィールド):カレンダー
- 出力ファイル名:calendar.php
- テンプレートの種類:カスタムインデックステンプレート
- ファイルへのリンク:(設定不要)
- 公開:ダイナミック
- テンプレートの内容(テキストエリア):下記のいずれか
デフォルトテンプレートの場合
<mt:GetQueryString name="date" setvar="yearmonth" />
<mt:GetQueryString name="date" regex_replace="/^(\d\d\d\d).*/","\$1" setvar="year" />
<mt:GetQueryString name="date" regex_replace="/.*(\d\d)$/","\$1" setvar="month"/>
<mt:GetVar name="month" op="--" setvar="prev_month" />
<mt:GetVar name="year" setvar="prev_year" />
<mt:if name="prev_month" eq="0">
<mt:SetVar name="prev_month" value="12" />
<mt:SetVar name="prev_year" op="--" />
</mt:if>
<mt:if name="prev_month" lt="10">
<mt:GetVar name="prev_month" regex_replace="/(.*)/","0\$1" setvar="prev_month" />
</mt:if>
<mt:GetVar name="month" op="++" setvar="next_month" />
<mt:GetVar name="year" setvar="next_year" />
<mt:if name="next_month" eq="13">
<mt:SetVar name="next_month" value="1" />
<mt:SetVar name="next_year" op="++" />
</mt:if>
<mt:if name="next_month" lt="10">
<mt:GetVar name="next_month" regex_replace="/(.*)/","0\$1" setvar="next_month" />
</mt:if>
<div class="widget-calendar widget">
<h3 class="widget-header">
<a href="javascript:void(0);" onclick="getCalendar('<mt:BlogURL />calendar.php?date=<mt:getvar name="prev_year" /><mt:getvar name="prev_month">');"><</a>
<mt:GetVar name="year" />年<mt:GetVar name="month" />月
<a href="javascript:void(0);" onclick="getCalendar('<mt:BlogURL />calendar.php?date=<mt:getvar name="next_year" /><mt:getvar name="next_month">');">></a>
</h3>
<div class="widget-content">
<table summary="<mt:GetVar name="year" />/<mt:GetVar name="month" />">
<tr height="15">
<th abbr="Sunday" class="sunday">Sun</th>
<th abbr="Monday">Mon</th>
<th abbr="Tuesday">Tue</th>
<th abbr="Wednesday">Wed</th>
<th abbr="Thursday">Thu</th>
<th abbr="Friday">Fri</th>
<th abbr="Saturday" class="saturday">Sat</th>
</tr>
<mt:Calendar month="$yearmonth">
<mt:CalendarWeekHeader>
<tr>
</mt:CalendarWeekHeader>
<td><mt:CalendarIfBlank><mt:Else><span></mt:Else></mt:CalendarIfBlank><mt:CalendarIfEntries><mt:Entries lastn="1"><a href="<mt:EntryLink archive_type="Daily" />"><mt:CalendarDay /></a></mt:Entries></mt:CalendarIfEntries><mt:CalendarIfNoEntries><mt:CalendarDay /></mt:CalendarIfNoEntries><mt:CalendarIfBlank><mt:Else></span></mt:Else></mt:CalendarIfBlank></td>
<mt:CalendarWeekFooter>
</tr>
</mt:CalendarWeekFooter>
</mt:Calendar>
</table>
</div>
</div>
公開テンプレートの場合
<mt:GetQueryString name="date" setvar="yearmonth" />
<mt:GetQueryString name="date" regex_replace="/^(\d\d\d\d).*/","\$1" setvar="year" />
<mt:GetQueryString name="date" regex_replace="/.*(\d\d)$/","\$1" setvar="month"/>
<mt:GetVar name="month" op="--" setvar="prev_month" />
<mt:GetVar name="year" setvar="prev_year" />
<mt:if name="prev_month" eq="0">
<mt:SetVar name="prev_month" value="12" />
<mt:SetVar name="prev_year" op="--" />
</mt:if>
<mt:if name="prev_month" lt="10">
<mt:GetVar name="prev_month" regex_replace="/(.*)/","0\$1" setvar="prev_month" />
</mt:if>
<mt:GetVar name="month" op="++" setvar="next_month" />
<mt:GetVar name="year" setvar="next_year" />
<mt:if name="next_month" eq="13">
<mt:SetVar name="next_month" value="1" />
<mt:SetVar name="next_year" op="++" />
</mt:if>
<mt:if name="next_month" lt="10">
<mt:GetVar name="next_month" regex_replace="/(.*)/","0\$1" setvar="next_month" />
</mt:if>
<table summary="<mt:GetVar name="year" />/<mt:GetVar name="month" />">
<caption class="calendarhead">
<a href="javascript:void(0);" onclick="getCalendar('<mt:BlogURL />calendar.php?date=<mt:getvar name="prev_year" /><mt:getvar name="prev_month">');"><</a>
<mt:GetVar name="year" />年<mt:GetVar name="month" />月
<a href="javascript:void(0);" onclick="getCalendar('<mt:BlogURL />calendar.php?date=<mt:getvar name="next_year" /><mt:getvar name="next_month">');">></a>
</caption>
<tr height="15">
<th abbr="Sunday" class="sunday">Sun</th>
<th abbr="Monday">Mon</th>
<th abbr="Tuesday">Tue</th>
<th abbr="Wednesday">Wed</th>
<th abbr="Thursday">Thu</th>
<th abbr="Friday">Fri</th>
<th abbr="Saturday" class="saturday">Sat</th>
</tr>
<mt:Calendar month="$yearmonth">
<mt:CalendarWeekHeader>
<tr>
</mt:CalendarWeekHeader>
<td><mt:CalendarIfBlank><mt:Else><span></mt:Else></mt:CalendarIfBlank><mt:CalendarIfEntries><mt:Entries lastn="1"><a href="<mt:EntryLink archive_type="Daily" />"><mt:CalendarDay /></a></mt:Entries></mt:CalendarIfEntries><mt:CalendarIfNoEntries><mt:CalendarDay /></mt:CalendarIfNoEntries><mt:CalendarIfBlank><mt:Else></span></mt:Else></mt:CalendarIfBlank></td>
<mt:CalendarWeekFooter>
</tr>
</mt:CalendarWeekFooter>
</mt:Calendar>
</table>
テンプレートの設定部分は次のようになります。

6.テンプレート修正
6.1 外部ファイルのインクルード
ブログ管理画面の「デザイン」→「テンプレート」→「テンプレートモジュール」→「HTMLヘッダー(公開テンプレートの場合は「ヘッダー」)」をクリックし、下記の内容を追加して「保存」をクリック。
<script type="text/javascript" src="<$MTBlogURL$>prototype.js"></script>
<script type="text/javascript" src="<$MTBlogURL$>ajaxCalendar.js"></script>
<script type="text/javascript" src="<$MTBlogURL$>dayChecker.js"></script>
注:利用しているテンプレートによって設定位置が異なりますが、ブラウザでページを表示したときに <head>~</head> の間(</head> の直前を推奨)になるように設定します。
6.2 カレンダー表示部分の設定
「デザイン」→「ウィジェット」→ウィジェットテンプレートの「カレンダー」をクリックし、下記の内容に入れ替えたあと、「保存」をクリックします。「カレンダー」ウィジェットがない場合は、「ウィジェットテンプレートを作成」をクリックして以下の内容を設定してください。
<div id="calendar"></div>
<script type="text/javascript">
getCalendar("<$MTBlogURL$>calendar.php?date=<MTDate format="%Y%m" $>");
</script>
div は空要素ですが、Ajax によってこの部分にカレンダーが表示されます。
修正した「カレンダー」ウィジェットを利用していない場合は、ブログ管理画面の「デザイン」→「ウィジェット」をクリック、さらに利用しているウィジェットセットをクリックし、「インストール済み」にドラッグして「変更を保存」をクリックしてください。
7.CSS修正
「デザイン」→「テンプレート」→「スタイルシート」を選択し、下記の内容を追加して「保存および再構築」をクリックします。
#calendar {
margin: 5px 0 10px;;
color: #444444;
}
.calendarhead {
padding-bottom: 5px;
font-size: 9px;
letter-spacing: 0.2em;
}
#calendar table {
padding: 0;
border-collapse: collapse;
}
#calendar th {
padding-bottom: 3px;
text-align: center;
font-size: 9px;
width: 23px;
}
#calendar td {
padding: 2px 0;
text-align: center;
font-size: 10px;
line-height: 120%;
}
.today {
display: block;
border: 1px solid #444444;
}
.sunday,
.holiday,
.holiday a:link,
.holiday a:visited {
color: #e50003;
}
.saturday,
.saturday a:link,
.saturday a:visited {
color: #0000ff;
}
公開テンプレートの場合、すでにカレンダー関係のスタイル設定が行われており、設定の競合を避けるため、古い設定(下)を削除またはコメントアウトしてください。
/* カレンダー */
.calendarhead {
padding-bottom: 5px;
text-align: center;
color: #333;
font-size: 9px;
background: none;
letter-spacing: 0.2em;
}
#calendar table {
text-align: center;
padding: 0px;
border-collapse: collapse;
}
#calendar th {
padding-bottom: 3px;
font-size: 8px;
width: 23px;
}
#calendar td {
padding: 2px 0;
font-size: 9px;
line-height: 120%;
}
span.day {
text-align: center;
font-size: 9px;
}
span.saturday {
color: blue;
}
span.sunday {
color: #e50003;
}
td.today {
display: block;
border: 1px solid #333;
}
8.再構築
全てのページを再構築します。これでメインページ等を表示してカレンダーが表示されれば完成です。
9.注意事項
日別アーカイブは先に再構築しておいてください。日別アーカイブがなくても再構築エラーにはなりませんが、日付のリンクから日別アーカイブに移動できません。
10.その他
このカスタマイズではインデックステンプレートのみを使用しましたが、ブログ記事のある月はアーカイブテンプレート、そうでない月はインデックステンプレートを利用するという、ハイブリッドな月送りカレンダーについても検討中です。
Movable Type 4.2 のダイナミックパブリッシングでプロフィール画像関連のテンプレートタグが動作しない不具合について
Movable Type 4.2(動作確認は4.261)でダイナミックパブリッシングを使用している場合、プロフィール画像関連のテンプレートタグが正常に動作しないケースがあります。
ご質問を頂きましたので、本エントリーにて情報展開致します。
1.事象
例えば、プロフィール画像を登録しているユーザーがコミュニティブログに記事を投稿した場合、スタティックパブリッシングではメインページで次のようにプロフィール画像が表示されます。
スタティックパブリッシング

このページをダイナミックパブリッシングにするとデフォルトの画像になります。
ダイナミックパブリッシング

なお、いくつかのテンプレートタグを試したところ、以下のテンプレートタグから正常な出力を得られませんでした。
- MTAuthorUserpic
- MTAuthorUserpicURL
- MTEntryAuthorUserpic
- MTEntryAuthorUserpicURL
2.原因
php のソースをトレースしたところ、上記の各テンプレートタグの処理で php/lib/MTUtil.php の userpic_url という関数を起動しています。この関数はプロフィール画像のURLを返却するもので、その中で次の処理がありました。
if (!$thumb->get_thumbnail($dest, $thumb_w, $thumb_h, $asset['asset_id'], $scale, $thumb_name, 'png', true)) {
return '';
}
赤字の部分が示すように、png 画像に限定した処理になっています。テストしたプロフィール画像は jpg だったため、この処理でエラーとなり、テンプレートタグで何も表示されなかったようです。最初に png 画像で実験していたら、この原因には気がつかなかったと思います。
ちなみに、冒頭に示した画像がデフォルトのプロフィール画像になるのは、次のように MTIf タグで MTEntryAuthorUserpicURL タグを判定しているためです(分かりやすくするため改行しています)。
<img src="
<mt:If tag="EntryAuthorUserpicURL">
<$mt:EntryAuthorUserpicURL$>
<mt:Else>
<$mt:StaticWebPath$>images/default-userpic-90.jpg
</mt:If>
" width="<$mt:Var name="userpic_size"$>" height="<$mt:Var name="userpic_size"$>" alt="user-pic" />
3.対処
根本的な解決ではありませんが、とりあえずプロフィール画像に png を利用すれば、ダイナミックパブリッシングでも正常に画像が表示されます。
4.Windows での挙動
Windows(XPなので公式のインストール環境ではありません)では、パスのセパレータが「¥」になるのですが、png 画像を利用しても、次のようにプロフィール画像のパスに「/」と「¥」が混在してしまって正常に画像が表示できないようです。
/mt-static/support/assets_c¥userpics/userpic-1-100x100.png
とりあえず、php/lib/MTUtil.php の userpic_url の処理を一部書き換えると正常に表示できるようになりました。赤字を削除して青字の内容に書き換えます。
...前略...
function userpic_url($asset, $blog, $author) {
global $mt;
$format = $mt->translate('userpic-[_1]-%wx%h%x', array($author['author_id']));
$max_dim = $mt->config('UserpicThumbnailSize');
# generate thumbnail
$src_file = asset_path($asset['asset_file_path'], $blog);
$cache_path = $mt->config('AssetCacheDir');
$image_path = $cache_path . DIRECTORY_SEPARATOR . 'userpics';
$image_path = $cache_path . '/' . 'userpics';
$static_file_path = static_file_path().'support';
...後略...
ダイナミックパブリッシングによるページ分割
Movable Type 4.2 ではダイナミックパブリッシングによるページ分割が行なえます。
カテゴリーアーカイブのページナビゲーション

月別アーカイブのページナビゲーション

メインページのページナビゲーション

本エントリーでは、以下の解説を元に「既定のブログ」へのページ分割設定方法を紹介します。
1..htaccess の変更(4.2 以前からダイナミックパブリッシングを導入している場合)
参考とした元記事では 以下のように .htaccess の変更を行なっていますが、4.2 からダイナミックパブリッシングの運用を開始している場合は設定不要です。
変更前
RewriteRule ^(.*)$ $mtview_server_url [L,QSA]
変更後
RewriteRule ^(.*)(\?.*)?$ $mtview_server_url$2 [L,QSA]
2.「ブログ記事リスト」アーカイブテンプレートにページナビゲーションの追加
ブログ記事管理画面の「デザイン」→「テンプレート」→「カテゴリ別ブログ記事リスト(または月別ブログ記事リスト)」をクリックし、以下のサブテンプレート(青色部分)を追加します。
...前略...
<div class="content-nav">
<mt:ArchivePrevious><a href="<$mt:ArchiveLink$>">« <$mt:ArchiveTitle$></a> |</mt:ArchivePrevious>
<a href="<$mt:Link template="main_index"$>">メインページ</a> |
<a href="<$mt:Link template="archive_index"$>">アーカイブ</a>
<mt:ArchiveNext>| <a href="<$mt:ArchiveLink$>"><$mt:ArchiveTitle$> »</a></mt:ArchiveNext>
</div>
<div class="content-nav">
<mt:IfPreviousResults><a href="<mt:PreviousLink encode_html="1">" rel="prev">« Previous</a> </mt:IfPreviousResults>
<mt:PagerBlock>
<mt:IfCurrentPage><mt:Var name="__value__"><mt:Else><a href="<mt:PagerLink encode_html="1">"><mt:Var name="__value__"></a></mt:IfCurrentPage>
<mt:unless name="__last__"> </mt:unless>
</mt:PagerBlock>
<mt:IfMoreResults> <a href="<mt:NextLink encode_html="1">" rel="next">Next »</a>
</mt:IfMoreResults>
</div>
</div>
...後略...
3.アーカイブテンプレートの修正
1項の編集画面を開いた状態で、MTEntries タグに offset="auto" を追加し、limit="xx" でページ単位の表示数を設定します。$limit はそのまま使っても構いません。
変更前
<mt:Entries limit="$limit">
変更後
<mt:Entries limit="10" offset="auto">
これでアーカイブページにアクセスすればページ分割が行なえると思います。
なお、カテゴリアーカイブについては、MTEntriesWithSubCategories タグでも動作確認できました。
4.メインページについて
メインページもブログ記事リストのアーカイブページと同様の方法でページ分割可能ですが、ブログ内のすべてのブログ記事がページ分割対象となるため、カスタマイズが必要です(別の機会にエントリーしたいと思います)。
ダイナミック・パブリッシングで perl のプラグインを利用する
Movable Type のダイナミック・パブリッシングを利用する際、外部で配布されているMTプラグインの適用にあたっては制約があります。このエントリーではこれを解消する方法をいくつか紹介したいと思います。
ダイナミック・パブリッシングのメリットとスタティック・パブリッシングの併用
Movable Type のダイナミック・パブリッシング機能を利用することで、再構築処理が大幅に削減、あるいは不要になることについて、ご存知の方も多いと思います。これを利用すればブログでよくみかける「再構築に時間がかかる」とか「500エラーになる」という問題が減るかもしれません。*1
ただし、ダイナミック・パブリッシングはページ表示時にデータベースから情報を収集し、再構築を行なうため、アクセスが多いとその分サーバに負荷がかかります。「キャッシュ機能」や「条件付きGET」を利用すればこの問題を解消することは可能ですが、本来的にはアクセスの多いメインページやRSSフィードはスタティック・パブリッシング(静的なファイルを出力)にすることが望ましいと考えます。
特にレンタルサーバを使用する場合、この条件が重要になってきます。ダイナミック・パブリッシングはページ表示を PHP で処理するのですが、PHP が CGI で稼動するレンタルサーバでは、モジュール版で動作する場合よりレスポンスがやや遅く、サーバにも負荷がかかります。詳細は「PHP における「モジュール版」と「CGI 版」の比較 + WordPress の適用例」をご覧ください。
Movable Type の良い点は、アーカイブ別にダイナミック・パブリッシング/スタティック・パブリッシングを選択できることです。
先に述べたように、メインページやRSSフィードはスタティック・パブリッシングにし、カテゴリー・アーカイブや日付アーカイブ等をダイナミック・パブリッシングにするといった、アクセスに応じて柔軟な対応が可能です。
ダイナミック・パブリッシングの問題
ここからが本題です。そういう訳で個人的には Movable Type のダイナミック・パブリッシング機能は非常に優れていると感じているのですが、利用するにあたっては問題がひとつあります。それは
- ダイナミック・パブリッシング対応のMTプラグインが少ない
ということです。ここで言う「MTプラグイン」は、変数タグ・コンテナタグ・条件タグといった、テンプレートに記述するMTタグを提供するものを指します。
ダイナミック・パブリッシングを行う場合、標準のMTタグは Perl で実装されたプログラムを処理するのではなく、PHP(Smarty)が動作します。Movable Type のインストールアーカイブに php/lib ディレクトリがあると思いますが、この配下にダイナミック・パブリッシング用のタグおよびグローバルアトリビュートのプログラムが配置されています。
したがって、MTタグを提供するプラグインをダイナミック・パブリッシングで利用する場合、標準のMTタグと同様に PHP の実装が条件となります(プラグインに php ディレクトリが存在すれば多分対応しています)。
現在、当サイトで公開している「Movable Type プラグイン一覧」で挙げているプラグインは 200 を越えていますが、多くのプラグインが対応していないのではないかと推測します(私自身然り)。またこれがダイナミック・パブリッシングがメジャーにならない要因のひとつでかもしれないと懸念しています。
前置きが長くなりましたが、この問題を解消する方法等についていくつか紹介したいと思います。同時にダイナミックパブリッシングに精力的に活動されているサイトも紹介させて頂きます。
1.MTIncludeタグを利用する
これは、ダイナミック・パブリッシングに対応していないMTタグを使ったリスト等を、一旦インデックス・テンプレートにモジュール(部品)として追加し、それをダイナミック・パブリッシングしたアーカイブから MTInclude タグ+ file 属性を利用して引き込むというテクニックです。
このテクニックは下記のサイトで詳しく紹介されています。
「WingMemo」さんのところではダイナミック・パブリッシングに関する記事が多く掲載されています。ダイナミック・パブリッシングを検討されている方の手助けになると思いますので是非ご利用ください。
なお、このテクニックで作成したインデックス・テンプレートは必ず「インデックス・テンプレートを再構築するときに、このテンプレートを自動的に再構築する」にチェックを入れてください。
試しに MTCollate を使った「最近のコメント」を出力してみたところバッチリでした。
2.PHP化されたプラグインを利用する
「あんちもん2.Lab」さんは、個人プロジェクトとして Perl 版プラグインをダイナミックパブリッシング対応にリファクタリング(PHPize)されているサイトです。
これまでにもいくつかの既存プラグインをダイナミック・パブリッシング対応にされており、先の MTInclude で対応できないケースもこのリファクタリングで解決することができます。個人的には大変期待しておりますので、「このプラグインをダイナミック・パブリッシング対応して欲しい!」とお願いすれば作ってもらえるかもしれません。*2
3.Perl 版ダイナミックパブリッシングを利用する
「The blog of H.Fujimoto」さんで配布されている、Perl 版のダイナミック・パブリッシングを利用することで、ダイナミック・パブリッシングに対応していないプラグインをそのまま利用することができます。
ダイナミックパブリッシングの今後
サイトを訪問する側からすればストレスなくページが表示されることが好ましいので、全ページをスタティック・パブリッシングとするのが望ましいのですが、大量の記事を有するサイトでの運営の効率化を考慮すると、ダイナミック・パブリッシングは今後益々有効な手段として利用されていくのではないでしょうか。
私自身、サイトのダイナミック・パブリッシング化を検討していますし(それ以前に3.3にアップグレードしなければですが)、冒頭に述べたモジュール版 PHP がレンタルサーバ界に普及することが、Movable Type に限らず、ページを動的生成するブログがスタティック・パブリッシングに近づくための重要な要素のひとつであると思います。
*1:サーバのスペックによっては解消しない場合もあります。
*2:元サイトの配布プラグインのライセンスによっては対応できないものもあります。
Fast Search でカテゴリーの絞込み検索をする
先週紹介した「Movable Type で高速検索を実現する Fast Search プラグイン」ではオプションとしてカテゴリーの絞込み検索を行うことができます。
このエントリーでは Fast Search の検索フォームにカテゴリー選択のプルダウンメニューを追加する方法をご紹介します。
プラグイン配布元ではカテゴリーで絞込みを行う場合は、検索フォームに、
<input type="hidden" name="category" value="5" />
というような input 属性を追加する説明がありますが、カテゴリー ID はプルダウンメニューから設定できるようにします。
1.デフォルトテンプレートの場合
リストの青色部分が Fast Search の検索フォームに追加した箇所です。
<div class="module-search module">
<h2 class="module-header">検索</h2>
<div class="module-content">
<form method="get" action="<$MTBlogURL$><$MTFastSearchScript>">
<input type="hidden" name="IncludeBlogs" value="<$MTBlogID$>" />
<label for="search" accesskey="4">ブログを検索: </label><br />
<input id="query" name="query" size="20" />
<select name="category">
<option value="0">全カテゴリーを検索</option>
<MTCategories>
<option value="<$MTCategoryID$>"><MTParentCategories glue=" > "><$MTCategoryLabel$></MTParentCategories></option>
</MTCategories>
</select>
<input type="submit" value="検索" />
</form>
</div>
</div>
2.公開テンプレートの場合
<div class="side">
<form method="get" action="<$MTBlogURL$><$MTFastSearchScript>">
<input type="hidden" name="IncludeBlogs" value="<$MTBlogID$>" />
<label for="search" accesskey="4">ブログを検索: </label><br />
<input id="query" tabindex="5" accesskey="t" name="query" size="20" value="" /><br />
<select name="category">
<option value="0">全カテゴリーを検索</option>
<MTCategories>
<option value="<$MTCategoryID$>"><MTParentCategories glue=" > "><$MTCategoryLabel$></MTParentCategories></option>
</MTCategories>
</select>
<input type="submit" tabindex="6" accesskey="s" value="Search" />
</form>
</div>
3.注意事項
サンプルで追加したプルダウンメニューは、サブカテゴリーの左側に、">" をセパレータとして親カテゴリーを表示していますが、現実的にはカテゴリー名全体が横に長くなる場合が少なくないと思われます。横に長くなり過ぎると、プルダウンメニューがサイドメニューからはみ出す可能性があります。
カテゴリー名がはみ出さないようにするには、サブカテゴリーのみ表示するように、
<option value="<$MTCategoryID$>"><MTParentCategories glue=" > "><$MTCategoryLabel$></MTParentCategories></option>
の部分を
<option value="<$MTCategoryID$>"><$MTCategoryLabel$></option>
に変更してください。
Movable Type で高速検索を実現する Fast Search プラグイン
ダイナミック・パブリッシングを利用して Movable Type の高速検索を実現する Fast Search プラグインを紹介します。
このプラグインは、3.2x および 3.3x の検索結果テンプレートで利用している MT タグを php で利用可能にしたもので、テキスト検索、3.3x ではタグ検索も可能になっています。実験した感想としては検索レスポンスが数倍向上します。
なおプラグイン適用条件として、下記を満たしている必要があります。
- Movable Type 3.2 or 3.3
- MySQL 4.0.1 以上
1.プラグインのダウンロード
下記のサイトにある「Dowmload Now」のリンクをクリックして、プラグインをダウンロード。非商用サイトは無償で寄付を受け付けています。商用サイトは $97.00 です。
2.プラグインのアップロード
まず解凍した時のディレクトリ構造は下の通りです。
/FastSearch
/php
/plugins
block.MTBlogResultFooter.php
:
modifier.google_highlight.php
/plugins
/FastSearch
/tmpl
fast_search.tmpl
widget_fast_search.tmpl
FastSearch.pl
/PluginNetwork
PluginNetwork.pl
これを次の通りにアップロードします。
- FastSearch/php/plugins 配下のファイルをインストールディレクトリの mt-dir/php/plugins に全てアップロード
- FastSearch/plugins をインストールディレクトリの mt-dir/plugins にフォルダごと全てアップロード。mt/plugins の下に FastSearch および PluginNetwork ディレクトリが配置されるようにしてください。
3.アップグレード
プラグインをアップロード後、管理ページにログインするとアップグレード画面が表示されます。
驚かずに粛々と作業を進めてください。
アップグレード完了後、管理ページに再度ログインします。
4.ダイナミックパブリッシングの設定
Fast Search プラグインを利用にするために、ダイナミックパブリッシングの設定を行います。ダイナミックパブリッシングをご利用でない(各ページをスタティックに出力している場合)、メインページや他のアーカイブページをダイナミックパブリッシングに変更する必要はありません。
ブログ別管理画面の[設定] - [公開]を選択し、「再構築オプション」を「テンプレート別に、スタティックHTMLもしくはダイナミック・パブリッシングを選択します」を選択します。これで「変更を保存」をクリックします。
この時、メインページのあるディレクトリにダイナミックパブリッシングを有効にするための .htaccess および templates_c ディレクトリが自動生成されます。
5.Fast Search 設定1(初期設定)
ブログ別管理画面の[設定] - [プラグイン]を選択し、一覧に表示されている「Fast Search」の右側にある「設定を表示」をクリックします。これで設定画面(下)が開きます。
まず「Enable Fast Search」をチェックしてプラグインを有効にしてください。
「Search Results Per Page」および「Enable Logging」の設定もこの時に同時に設定することができます。
設定後、「変更を保存」をクリックします。
6.Fast Search 設定2(検索結果表示用テンプレート生成)
再度、 プラグイン一覧に表示されている「Fast Search」の右側にある「設定を表示」をクリックします。そして「Click here to install the default Fast Search Template.」のリンクをクリックしてください。
これで Fast Search 検索結果表示用の特殊なインデックステンプレートが生成され、その画面に遷移します(すでに保存されているので「保存」をクリックする必要はありません)。
また前段の作業でダイナミックパブリッシングの設定をしているので、再構築オプション自動的に「このテンプレートをダイナミック・ページにする」にチェックがつきます。もし後からダイナミックパブリッシングの設定を行なった場合は、このテンプレートに対しダイナミックパブリッシングで動作する設定(=チェックボックスのチェック)を行なってください。
これがプラグインで用意されている検索結果画面テンプレートですが、3.3x の検索結果画面デフォルトテンプレート、あるいは当サイトで配布している検索結果画面テンプレートに丸ごと入れ替えても正常に動作します。
7.Fast Search 設定3(検索フォーム)
Fast Search 用のフォームは、既存の
<form method="post" action="<$MTCGIPath$><$MTSearchScript$>"
を
<form method="post" action="<$MTBlogURL><$MTFastSearchScript>"
に変更すればOKです。
またはプラグインから Widget を生成することもできます。その場合は先のプラグイン設定画面にある、「Click here to install the Fast Search Widget.」のリンクをクリックします。これでテンプレートモジュールとしての検索フォーム「Widget: Fast Search」が生成されます。

このテンプレートモジュールを Widget ではなく、MTInclude タグで引き込むこともできます。その場合は検索フォームを表示させたいテンプレートのサイドバー部分に下記の1行を追加します。
<$MTInclude module="Widget: Fast Search"$>
8.Fast Search 設定4(FastSearch Method)
プラグインの設定画面で、もうひとつ「FastSearch Method」というプルダウンメニューの選択による設定項目があり、それぞれ下記のような意味があります。
- FullText:MySQLに標準搭載されている全文検索インデックス
- Non-FullText:上記以外
- Fallback:FullText を試行し、NGであれば Non-FullText で実行
FullText が一番良さそうなのですが、環境によってはエラーが発生します(実験サイトで試したところ、正常に動作する時とそうでない時がありました)。
調べてみたところ、FullText での日本語の全文検索については制約があるようです(詳細は9項の関連記事参照)。また Fallback では FullText を試みますが、失敗した場合は FullText のエラーが画面に表示されてしまうので、FullText を選択してエラーが解消しない場合は Non-FullText を選択するのが無難でしょう(FullText の適切な設定方法があればご教示ください)。
これで Fast Search の検索フォームより検索を実行し、検索結果が正常に表示されれば完了です。
9.ダイナミック・パブリッシングのチューニング
これで検索処理は高速になりますが、Movable Type デフォルトの検索機能の「連続実行抑止時間」の設定はありません。その結果サーバへの負荷拡大が予想されます。モジュール版PHPであればまだ良いのですがCGI版PHPの場合はプログラム実行とみなされます(参考:PHP における「モジュール版」と「CGI 版」の比較 + WordPress の適用例)。
したがって、「Movable Type の再構築を不要にする「ダイナミック・パブリッシング」(その2:設定方法)」の3項で解説しているように、ページレベルのキャッシングや条件付きGETの設定し、サーバの負荷を少しでも軽減することをお勧めします。
なおタグ検索は有効と思われますが、テキスト検索では検索文字列が不定なため、どれほどの効果があるかは分かりません。
10.関連記事
Movable Type の再構築を不要にする「ダイナミック・パブリッシング」(その2:設定方法)
その2ではダイナミック・パブリッシングの具体的な設定方法を記します。前提条件を満たしていれば、さほど難しい設定はありません。
1.ダイナミック・パブリッシングの条件
1.1 データベース
まず、使用データベースに
- MySQL
- PostgreSQL
- SQLiteバージョン2
が利用されていることが必要です。
もし BerkeleyDB や SQLite を利用されているのであればデータベースの移行が必要になります。データベース移行については下記の記事が参考になるでしょう。
1.2 HTTPサーバ
.htaccess が利用できる必要があります。レンタルサーバであれば大体利用できる設定になっていると思いますが、自宅サーバで Apache をご利用であれば httpd.conf に以下のような記述を追加します。ディレクトリはご自身の環境にあわせてください。
<Directory /usr/local/apache/htdocs/mt> AllowOverride All </Directory>- リスト1 httpd.conf
IISをお使いの場合は、403と404のエラーに対して、mtview.phpへのURLを設定してください(とマニュアルに記載されています)。
2.ダイナミック・パブリッシングの設定方法
2.1 再構築オプションの変更
Movable Type の管理画面から[設定]-[公開]の「公開」欄にある「再構築オプション」から下記のいずれかを選択し、「変更を保存」をクリックします。
「アーカイブのみダイナミック・パブリッシングで出力します」を選択
![]()
「テンプレート別に、スタティックHTMLもしくはダイナミック・パブリッシングを選択します」を選択
![]()
なお、1.2項で説明した .htaccess は、上記を選択し「変更を保存」をクリックした時点で生成されます。
後者を選択した場合は、さらに各テンプレートの編集ページで「このテンプレートをダイナミック・ページにする」のチェックボックスをチェックします。チェックして保存すると、そのテンプレートがダイナミック・パブリッシングの対象になり、再構築ボタンが非表示になります。 |
インデックス・テンプレートはスクリーンショットのような選択画面が表示されますので、「このテンプレートをダイナミック・ページにする」にチェックをして保存すれば、下の「インデックス・テンプレートを再構築するときに、このテンプレートを自動的に再構築する」のチェックボックスは非表示になります。 |
2.2 テンプレート・キャッシュ・ディレクトリの作成
ブログのルート・ディレクトリに templates_c という名前で新しいディレクトリを作成し、パーミッションを777に設定します。ディレクトリを作成しないとページが正常に表示されません。
3.ダイナミック・パブリッシングの最適化
以下の設定を行うことでダイナミック・パブリッシングを最適化します。
3.1 ページ・レベルのキャッシング
その1で説明した通り、Movable Type ではページのキャッシュ機能があります。この機能を利用すれば、あるページに対するリクエストで、そのページがファイルとしてキャッシュされます(ファイル名は外部から認識できない文字列)。
キャッシングを有効にするには、ブログのルート・ディレクトリに cache という名前のディレクトリを作成し、パーミッションを777に設定します。
次に、Dynamic Site Bootstrapperテンプレート(mtview.php)に青色の行を加えます。
<?php include('<$MTCGIServerPath$>/php/mt.php'); $mt = new MT(<$MTBlogID$>, '<$MTConfigFile$>'); $mt->caching =true; $mt->view(); ?>- リスト2 Dynamic Site Bootstrapperテンプレート
設定後、保存・再構築します。
これを利用すれば、(多分)テンプレートの内容が変更されるまでこのキャッシュが利用されるので、スタティック・パブリッシングに近いスピードでページにアクセスすることができます。
キャッシュを利用することでディスクは消費しますが、パフォーマンスは向上します。キャッシュはサーバの環境にあわせて利用を検討してください。個人的にはディスクの余裕があれば利用されることを推奨します。
3.2 条件付きリクエスト
ページ・レベルのキャッシングと排他的に利用すると思われるのが、この「条件付きリクエスト」です。機能としては、ページに変更がない状態でリクエストを受け付けた場合、304 Not Modified(サーバ上のファイルの変更がないためブラウザのキャッシュを用いることを示す)を返却します。
この設定を行うには、Dynamic Site Bootstrapperテンプレート(mtview.php)に青色の行を加えます。
<?php include('<$MTCGIServerPath$>/php/mt.php'); $mt = new MT(<$MTBlogID$>, '<$MTConfigFile$>'); $mt->conditional =true; $mt->view(); ?>- リスト3 Dynamic Site Bootstrapperテンプレート
設定後、保存・再構築します。
ダイナミック・パブリッシングを行うか、304 を返却するかの元情報は、ブログのコメント・トラックバック・テンプレート等のタイムスタンプを利用しているようです。
Movable Type の再構築を不要にする「ダイナミック・パブリッシング」(その1:概要)
「Movable Type で再構築ができません」「500エラーが多発します」という記事をよくみかけますが、Movable Type には WordPress のようなページの動的生成、いわゆる「ダイナミック・パブリッシング」がバージョン 3.1 から標準搭載されており、これを利用することで再構築不要な環境にすることができます。
「ダイナミック・パブリッシング」とは、リクエストが発生するたびにHTMLページを動的に生成する機能です。ちなみに「再構築」は、エントリー本文やコメント・トラックバック等のデータをデータベースから読み出して、スタティックなHTMLページを生成することです。
当サイトではこれまで「ダイナミック・パブリッシング」について全く取り上げていなかったのですが、今後は少しずつ記事として取り上げていきたいと考えています。
というのは、現在発売されている某雑誌で「Movable Type はスタティックなHTMLページ生成しかできません」ということが書かれており、Movable Type のブログツールとしての著名度に比べ「ダイナミック・パブリッシング」についての認知度が低いのではないかと懸念した次第です(私もその一人だったかもしれませんが)。
※スタティックページ生成を、ここでは便宜上「スタティック・パブリッシング」と称します。
1.スタティック・パブリッシングとダイナミック・パブリッシングの比較
まずは概要ということで、スタティック・パブリッシングとダイナミック・パブリッシングの各評価項目について、表で比較してみました。
| 項目 | スタティック | ダイナミック | ダイナミック・パブリッシングを設定したページおよび管理画面 |
|---|---|---|---|
| 再構築 | 要 | 不要 | 「ページを再構築する」という作業がなくなります(「保存」ボタンはデータベースに変更を反映させるだけ)。 |
| 再構築による500エラー | あり | なし *1 | 再構築がなくなりますので、500エラーが発生しなくなります。 |
| ページ表示 | 早い | やや遅い | アクセス毎にPHPを実行してページを生成するため、その分時間を要します。*2 |
| ディスク容量 | エントリー数に比例して増加 | 少 | スタティックページを生成しないため、ディスクの消費が少なくなります。*3 |
| エントリー削除後のHTMLファイル | 残らない *4 | 残らない | スタティックなファイルを生成しないので、誤って公開してしまったエントリーもアクセスされなくなります。 |
| コメント・トラックバック処理 | やや遅い | 早い | コメント・トラックバック受信によるスタティックページ生成処理がなくなる分、処理が早くなります。 |
| テンプレートタグ関連のプラグイン | 利用できる | 利用できない | PHPで動作するため、当サイトで公開している「Movable Type プラグイン一覧」で掲載しているテンプレートタグ(<MTxxx> みたいなもの)が使えない場合があります。*5 *6 |
どちらを選択するかについては、ご利用のサーバ環境等に依存します。
2.Movable Type でのメリット
1項に記していない、Movable Type を利用する際における大きなアドバンテージは、ダイナミック・パブリッシングとスタティック・パブリッシングをテンプレート単位に選択できることです。したがって、リクエストの多いメインページやRSSフィードはスタティック・パブリッシング、比較的アクセスが落ち着いている(と思われる)アーカイブページはダイナミック・パブリッシングで運用することが望ましいでしょう。
*1:単純に「ダイナミック・パブリッシング」にすれば、再構築のストレスから解消できるという訳でもないようです。例えば、ロリポップではサーバ+DBのパフォーマンスの問題か、「ダイナミック・パブリッシング」が快適に動作しないケースがあるようですので、導入する前にレンタルサーバのサポートやネット上で情報を入手されることをお勧めします。
*2:キャッシュ機能を利用することで改善されます。
*3:キャッシュ機能を利用するとディスクはその分必要になります。
*4:オプション設定が必要。詳細は「Movable Type のエントリー削除でHTMLファイルも自動的に削除する」参照。
*5:プラグインを利用したい場合は、The blog of H.Fujimoto さんの「再構築不要化カスタマイズ(MT3.3専用版)」をお勧めします。
*6:テンプレートタグ関連のプラグインはPHPで作成すれば対応可能(通常のプラグインはPerl)です。ダイナミック・パブリッシング用プラグインはほとんど出回っていない状況ですが、中には対応しているものもあります。
後者を選択した場合は、さらに各テンプレートの編集ページで「このテンプレートをダイナミック・ページにする」のチェックボックスをチェックします。チェックして保存すると、そのテンプレートがダイナミック・パブリッシングの対象になり、再構築ボタンが非表示になります。
インデックス・テンプレートはスクリーンショットのような選択画面が表示されますので、「このテンプレートをダイナミック・ページにする」にチェックをして保存すれば、下の「インデックス・テンプレートを再構築するときに、このテンプレートを自動的に再構築する」のチェックボックスは非表示になります。
