テンプレート・モジュールを使い倒して部品化のコンセプトは固まりましたか?それでは、PHPで軽量化を目指すためのカテゴリー・アーカイブの作成方法を説明します。
まずは、おさらいを兼ねてインデックス・テンプレートの作成から始めます。
部品化したい部分のうち、インデックス、各アーカイブ共通の部分については、インデックス・テンプレートで部品を作っておいて、表示の際にその部品を読み込むようにした方が効率的です。同じ内容なのに各ページにあらかじめ組み込んでおくのはディスク容量がもったいないですし、再構築にも時間が掛かります。
また、ちょっと考えてみてください。投稿時に再構築されるのはインデックスとその月の月別アーカイブ及び所属するカテゴリーの月別アーカイブです。その他のファイルは更新されません。これはどういうことかというと、例えば全てのページにカテゴリー一覧を表示し、そこに投稿数とか更新日とかを表示させるようにしていた場合、毎回毎回『すべてを再構築』しなければなりません。そうしなければ、昔作ったページや最近更新されていないカテゴリーインデックスでは件数とか更新日とかが古いままになってしまうのです。
したがって、各ページに共通のものを部品化しておくことのメリットは、容量とか再構築時間とかだけでなく、うまくやれば『すべてを再構築』などほとんどしないでよくなるわけですから、頑張ってみる価値があるというものです(笑)
インデックス・テンプレートの作成方法(おさらい)
共通している部品の例としては、『バナー』『フッター』『カテゴリー一覧』『年月一覧』などが挙げられるでしょう。まず、『新しいインデックス・テンプレートを作る』のリンクを押し、テンプレートの名前と出力ファイル名を決めます。名前は分かりやすければ何でもいいので『01バナー』とかでもいいでしょう。出力ファイル名も任意ですが、英語表記の方が無難でしょう。拡張子も何でもありのようですが私はincludeの頭文字で『inc』にしました。つまり、『banner.inc』としたわけです。
整理しますと
テンプレートの名前:01バナー
出力ファイル名:banner.inc
テンプレートの中身については、それまで使っていた部分をそのままカット&ペーストします。乱暴なようですが、大概はこれで動きます。
あとは、メインページやカテゴリーアーカイブなどの部品ファイルを読み込みたいページに
<?php readfile('絶対パス/banner.inc');?>
さて、次に各アーカイブ・テンプレートの作成方法をご説明します。
例えば、カテゴリー別のタイトル一覧を部品として用意しておきたいというニーズが考えられます。個別エントリーに所属するタイトル一覧を表示させればユーザビリティは上がると思いますが、一方、各ページにあらかじめ組み込んでおくのは容量も時間ももったいないです。そこで、『新しいアーカイブ・テンプレートを作る』をクリックして、テンプレートの名前を『CategoryEntryList』などとして、リンクファイルは空のまま、中身の部分に
<div class="sidetitleS">
【カテゴリの説明】<br />
<$MTCategoryDescription$></div>
<div class="side">
<MTEntries category=<$MTCategoryLabel$>
<a href="<$MTEntryPermalink$>"><$MTEntryDate format="%y/%m/%d"$> <$MTEntryTitle$></a><br />
</MTEntries>
</div>
これを保存して、読み込むわけですが、お気づきのとおり、このままではファイル名が無いので読み込めませんね。
そこで、『アーカイブ・ファイルのオプションを編集』に行きます。アーカイブの種類は上記の例では『カテゴリー』ですから、『カテゴリー』を選択し、テンプレートは今作ったテンプレート名(上記の例では『CategoryEntryList』)が選択できるようになっていますのでそれを選択して『追加』ボタンを押します。
すると、カテゴリー別のところに追加されました。後は、出力ファイルパスの指定です。これをしないと読み込めませんからね。
ここでちょっと考えていただきたいのですが、MTのディレクトリ構成を吟味すればカテゴリー別のフォルダの命名規則が安定していないことが分かるでしょう。ということは、カテゴリー別の部品といえどもそれぞれのディレクトリに補完するのはちょっと危険な香りがします。(うまく行くのかもしれませんが)素人は手を出さない方がいいでしょう。
そこで、カテゴリー別の部品ではありますが、私の場合はアーカイブファイルパス直下に置くことにしました。『アーカイブ・ファイルのテンプレート』というInputBoxに
<$MTCategoryLabel$>_list.inc
【2006/9/7追記】
カテゴリを任意の順番に並べ替える[cutfirstchar]の追記に記載したように、このエレガントさに関する問題点をクリアできる可能性が見つかりました(筆者はまだトライするか躊躇していますが)。
【2006/10/18追記】
カテゴリの概要にファイルパスを入れることで文字化けファイルの生成を回避できることが分かりました。
参照したのは『30代サラリーマンのためのMovableTypeで簡単!ホームページ管理』です。
カテゴリの概要は、基本的に出力ファイル名と同じ記述にします。例えば出力ファイル名が「10」であればカテゴリの概要も「10」と入力します。
但し、サブカテゴリ構造をとっている場合は、親カテゴリのファイル名も入れる必要があり、親が「10」で子が「11」である場合、親カテゴリのカテゴリの概要は「10」でいいですが、子カテゴリのカテゴリの概要は「10/11」と入力します。
一方、カテゴリーアーカイブファイルの出力ファイルの指定は
<$MTCategoryDescription$&rt;/list.inc
というように概要に記載したファイルパスを利用します。
これを個別アーカイブで読み込む場合は
<?php readfile('<$MTEntryLink archive_type="Category"$&rt;/list.inc');?&rt;
というような感じでできます。
なお、ご想像の通り、この場合、カテゴリの概要を本来の用途で使用することはできません。
【追記終了】
これで、ファイル名ができましたので、あとは読み込む方です。
先の例では、『個別エントリーが所属するカテゴリーリスト』ですから、組み込み先は当然個別エントリーアーカイブになります。
<?php readfile('絶対パス/<$MTEntryCategory$>_list.inc');?>
注意する点は、ファイルの出力先ではMTCategoryLabelタグを使ったのに対し、読み込み側ではMTEntryCategoryタグを使う点です。エントリーに属するタグとカテゴリーに属するタグとで共通なものとして、カテゴリー名しかありません(多分)。先の判断はプラグインを探すのは面倒だし、作るのは大変、ということでの妥協だったわけです。効率がいいのもエレガントの要素ですから(笑)
上記はカテゴリー別でしたが、月別でも応用すればすぐできます。しかし、カレンダー等月別の情報を個別やカテゴリー別に表示するのはあまり意味があるとは思えませんので、私は月別のアーカイブ・テンプレートは作成しておりません。
個別の場合も簡単な応用です。個別の場合は、『本文』『追記』『コメント』などが部品化できるでしょう。これらを部品化すると、インデックス、カテゴリー別、月別では表示の際にincludeすればいいので容量の節約につながるでしょう。
詳しくはBoycott Street 221Bに記載されていますので参考にしてください。なお、ファイルのパスですが、私の場合は、
<$MTArchiveDate format="%Y/%m/parts/"$><$MTEntryID$>_body.inc
この、部品化を行なうことで、ディスク容量は半分以下に減ると思います。ただし、ロリポップのユーザー管理画面でのディスク容量の数値はすぐにキャッシュが更新されないようです。また、再構築時間ですが格段に短くなります。
【2005/6/21追記】
『PHP化』のところでも追記しましたが、hohohoさんのご指摘を受けて、include関数を使うのをやめ、readfile関数を使うことにしました。今のところ、PHPプログラムには手を出していませんので。
http://yujiro.dyndns.org/blog/koikikukan/archives/2005/03/04-235533.php#comments
PHPモジュール化するのは良いのですがやや誤解があるかなと思います。を参照のこと。
投稿者: hohoho at 2005年06月21日 15:15ご指摘ありがとうございます。早速修正させて頂きます。
投稿者: Vulcan at 2005年06月21日 17:38http://website.kodakara.com/archives/2005/06/php.php#myExtend
いろいろ試したところ、入れ子にしている場合はInclude関数でないと駄目なようですね。識者には当たり前のことなのかもしれませんが。
投稿者: Vulcan at 2005年06月21日 21:31小粋空間: PHPモジュール化の仕組みについて(その3:変更方法)
http://yujiro.dyndns.org/blog/koikikukan/archives/2005/03/08-153818.php
インクルードが何段にもなる場合は、インクルード元に近い方から include 関数を用いて、一番末端だけ readfile 関数または include 関数を使用、という構造になります。
と書かれているわけで。。。
投稿者: hohoho at 2005年06月21日 22:53先の私のコメントは誤解をうむ表現でした。
hohohoさん、ご指摘ありがとうございます!