カテゴリーの階層別にデザインを切り替える for Movable Type 4
カテゴリーの階層別にデザインを切り替えるカスタマイズです。ポイントは「MTElseタグを使わない(使えない)」ということです。
参考記事は下記です。ありがとうございました。
以下に示すサブテンプレートは、ブログ記事リストへの設定を前提にしています。各サブテンプレートの一番外側のifタグは、ブログ記事リストでカテゴリーアーカイブと他のアーカイブを併用している場合を考慮したものです。
2階層の場合(パターン1)
<mt:if name="category_archive">
<MTHasParentCategory>
子カテゴリーのサブテンプレート
</MTHasParentCategory>
<MTHasNoParentCategory>
親カテゴリーのサブテンプレート
</MTHasNoParentCategory>
</mt:if>
2階層の場合(パターン2)
<mt:if name="category_archive">
<MTHasSubCategories>
親カテゴリーのサブテンプレート
</MTHasSubCategories>
<MTHasNoSubCategories>
子カテゴリーのサブテンプレート
</MTHasNoSubCategories>
</mt:if>
3階層の場合(パターン1)
<mt:if name="category_archive">
<MTHasSubCategories>
<MTHasNoParentCategory>
親カテゴリーのサブテンプレート
</MTHasNoParentCategory>
<MTHasParentCategory>
子カテゴリーのサブテンプレート
</MTHasParentCategory>
</MTHasSubCategories>
<MTHasNoSubCategories>
孫カテゴリーのサブテンプレート
</MTHasNoSubCategories>
</mt:if>
3階層の場合(パターン2)
<mt:if name="category_archive">
<MTHasParentCategory>
<MTHasSubCategories>
子カテゴリーのサブテンプレート
</MTHasSubCategories>
<MTHasNoSubCategories>
孫カテゴリーのサブテンプレート
</MTHasNoSubCategories>
</MTHasParentCategory>
<MTHasNoParentCategory>
親カテゴリーのサブテンプレート
</MTHasNoParentCategory>
</mt:if>
4階層の場合
<mt:if name="category_archive">
<MTHasSubCategories>
<MTHasNoParentCategory>
階層1カテゴリーのサブテンプレート
</MTHasNoParentCategory>
<MTHasParentCategory>
<MTParentCategory>
<MTHasParentCategory>
階層3カテゴリーのサブテンプレート
</MTHasParentCategory>
<MTHasNoParentCategory>
階層2カテゴリーのサブテンプレート
</MTHasNoParentCategory>
</MTParentCategory>
</MTHasParentCategory>
</MTHasSubCategories>
<MTHasNoSubCategories>
階層4カテゴリーのサブテンプレート
</MTHasNoSubCategories>
</mt:if>
次回はプラグインもしくは制御タグによる階層判定を行います。
カテゴリーリストの中に月別カテゴリーリストを表示する
カテゴリーリストと、そのカテゴリーがもつ月別カテゴリーリストを同時に表示するカスタマイズです。

カテゴリーリストはサブカテゴリーリストでも可能です。

カテゴリーリストの表示件数を絞り、かつ表示月が少ない場合に有効です。また、月別カテゴリーが有効になっていない場合は月別カテゴリーリストを表示しません。
デフォルトテンプレート(ウィジェット)+カテゴリーリスト
<MTIfArchiveTypeEnabled archive_type="Category">
<div class="widget-archive widget-archive-category widget">
<h3 class="widget-header">カテゴリ</h3>
<div class="widget-content"><ul class="widget-list">
<MTCategories>
<MTIfNonZero tag="MTCategoryCount">
<li class="widget-list-item"><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><$MTCategoryLabel$></a>
<MTIfArchiveTypeEnabled archive_type="Category-Monthly">
<MTArchiveList archive_type="Category-Monthly">
<MTArchiveListHeader>
<ul class="widget-list">
</MTArchiveListHeader>
<li class="widget-list-item"><a href="<$MTArchiveLink$>"><$MTArchiveTitle regex_replace="/.*: /",""$></a> [<$MTArchiveCount$>]</li>
<MTArchiveListFooter>
</ul>
</MTArchiveListFooter>
</MTArchiveList>
</MTIfArchiveTypeEnabled>
<MTElse>
<li class="widget-list-item"><$MTCategoryLabel$>
</MTIfNonZero>
</li>
</MTCategories>
</div>
</div>
</MTIfArchiveTypeEnabled>
デフォルトテンプレート(ウィジェット)+サブカテゴリーリスト
<MTIfArchiveTypeEnabled archive_type="Category">
<div class="widget-archive widget-archive-category widget">
<h2 class="widget-header">カテゴリ</h2>
<div class="widget-content">
<MTTopLevelCategories>
<MTSubCatIsFirst>
<ul class="widget-list">
</MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li class="widget-list-item"><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><$MTCategoryLabel$></a>
<MTIfArchiveTypeEnabled archive_type="Category-Monthly">
<MTArchiveList archive_type="Category-Monthly">
<MTArchiveListHeader>
<ul class="widget-list">
</MTArchiveListHeader>
<li class="widget-list-item"><a href="<$MTArchiveLink$>"><$MTArchiveTitle$></a> [<$MTArchiveCount$>]</li>
<MTArchiveListFooter>
</ul>
</MTArchiveListFooter>
</MTArchiveList>
</MTIfArchiveTypeEnabled>
<MTElse>
<li class="widget-list-item"><$MTCategoryLabel$>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast>
</ul>
</MTSubCatIsLast>
</MTTopLevelCategories>
</div>
</div>
</MTIfArchiveTypeEnabled>
そのうち折りたためるようにします。
サブカテゴリーリストを定義型リストでマークアップする
Movable Type の、2階層のサブカテゴリーリストで、定義型リスト(dl/dt/dd:または定義リスト)によるマークアップを実現する方法です。ここでは Movable Type によるカスタマイズを記していますが、定義型リストの使い方の参考にもなると思います。
以前、ご質問を頂いたもので、本エントリーで情報展開しておきます。
1.完成例
親カテゴリーに dt 要素、子カテゴリーは全体を dd 要素で括った後、順不同リスト(ul/li)でリスト表示します。
<dl>
<dt>親カテゴリーA</dt>
<dd>
<ul>
<li>子カテゴリーA-1</li>
<li>子カテゴリーA-2</li>
<li>子カテゴリーA-3</li>
</ul>
</dd>
<dt>親カテゴリーB</dt>
<dd>
<ul>
<li>子カテゴリーB-1</li>
<li>子カテゴリーB-2</li>
<li>子カテゴリーB-3</li>
</ul>
</dd>
</dl>
ちなみに、上のリストを順不同リストで表現すると、次のようになります。
<ul>
<li>親カテゴリーA
<ul>
<li>子カテゴリーA-1</li>
<li>子カテゴリーA-2</li>
<li>子カテゴリーA-3</li>
</ul>
</li>
</ul>
<ul>
<li>親カテゴリーB
<ul>
<li>子カテゴリーB-1</li>
<li>子カテゴリーB-2</li>
<li>子カテゴリーB-3</li>
</ul>
</li>
</ul>
2.サブテンプレート
上記を実現するサブテンプレートは次のようになります。
<dl>
<MTTopLevelCategories>
<MTSubCatIsFirst><MTHasNoParentCategory><MTElse><dd><ul></MTHasNoParentCategory></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<MTHasNoParentCategory>
<dt><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]</dt>
<MTElse>
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
</MTHasNoParentCategory>
<MTElse>
<MTHasNoParentCategory>
<dt><MTCategoryLabel></dt>
<MTElse>
<li><MTCategoryLabel>
</MTHasNoParentCategory>
</MTIfNonZero>
<MTSubCatsRecurse>
<MTHasNoParentCategory>
<MTElse>
</li>
</MTHasNoParentCategory>
<MTSubCatIsLast><MTHasNoParentCategory><MTElse></ul></dd></MTHasNoParentCategory></MTSubCatIsLast>
</MTTopLevelCategories>
</dl>
余談ですが、定義型リストによるマークアップは、以前行われた「コーディングコンテストVol.1」で最優秀賞を獲得された、「TOTOCO.ORG」さんのマークアップで利用されていて、審査員の方から「dl要素の使い方が良い」と、高い評価を受けています。
下の画面がコンテストで最優秀賞を得たサイトです。ブラウザから[表示]-[ページのソース]でマークアップをみることができます。
例えば、グローバルナビゲーションは次のようなマークアップです(一部省略しています)。
<dl id="globalNav">
<dt>主なカテゴリー</dt>
<dd>
<ul>
<li><a href="index.html"><img src="nav_home_cr.gif" alt="ホーム" width="98" height="54" /></a></li>
<li><a href="service/index.html"><img src="nav_biz.gif" alt="事業内容" width="98" height="54" /></a></li>
<li><a href="products/index.html"><img src="nav_products.gif" alt="製品情報" width="98" height="54" /></a></li>
<li><a href="recruit/index.html"><img src="nav_recruit.gif" alt="採用情報" width="98" height="54" /></a></li>
<li><a href="about/index.html"><img src="nav_about.gif" alt="会社概要" width="98" height="54" /></a></li>
<li><a href="contact/index.html"><img src="nav_contact.gif" alt="お問い合わせ" width="99" height="54" /></a></li>
</ul>
</dd>
</dl>
dt 要素は、次のCSSで非表示になっています(セレクタ名は一部省略)。
dl#globalNav dt{
position:absolute;
overflow:hidden;
width:0;
height:0;
}
丁度この時執筆していた、「Movable Type WEBデザインの新しいルール」のグローバルナビゲーションのカスタマイズにも、この定義型リストによるマークアップを利用させていただきました。
カテゴリーリストにカスタムフィールドの画像を表示する
Movable Type のカテゴリーリストに、カスタムフィールドの画像を表示するカスタマイズです。
次のように、カテゴリー別の画像を簡単に与えることができます。

1.カスタムフィールドの作成
カテゴリーにカスタムフィールドを作成します。ここでは CategoryImage という名前のテンプレートタグにします。

2.カテゴリーに画像の追加
各カテゴリーに表示されている「Imageを選択」をクリックして、画像を追加します。

画像を選択した後、必ず保存をクリックしてください。何回か試して正常に表示されないことがあったのですが、どうも保存をクリックするのを忘れていたようです。

3.サブテンプレートの追加
冒頭のサンプルは、デフォルトテンプレートのサイドバーに下記のサブテンプレートを追加しました。階層表示でない、MTCategories タグを久しぶりに使ってみました。
青色部分がカスタムフィールド用タグです。
<mt:IfArchiveTypeEnabled archive_type="Category">
<div class="widget-archive widget-archive-category widget">
<h3 class="widget-header">カテゴリ</h3>
<div class="widget-content">
<ul class="widget-list">
<mt:Categories>
<mt:ifNonZero tag="mt:CategoryCount">
<li class="widget-list-item"><MTCategoryImageAsset><img src="<$MTAssetURL$>" style="vertical-align:middle" /> </MTCategoryImageAsset><a href="<$mt:CategoryArchiveLink$>"<mt:IfNonEmpty tag="mt:CategoryDescription"> title="<$mt:CategoryDescription$>"</mt:IfNonEmpty>><$mt:CategoryLabel$> (<$mt:CategoryCount$>)</a>
<mt:else>
<li class="widget-list-item"><MTCategoryImageAsset><img src="<$MTAssetURL$>" style="vertical-align:middle" /> </MTCategoryImageAsset><$mt:CategoryLabel$>
</mt:ifNonZero>
</li>
</mt:Categories>
</ul>
</div>
</div>
</mt:IfArchiveTypeEnabled>
赤色部分は、画像の垂直方向の位置揃えのための style 属性です。サンプルでは img 要素に直接与えてしまっているので、適宜スタイルシートで設定するようにしてください。
ブログ記事に同一カテゴリーのブログ記事の前後リンクを表示する
Movable Type で、ブログ記事の前後のブログ記事へのリンクを、直近のブログ記事ではなく、同一カテゴリーのブログ記事を表示するカスタマイズです。
下の画面の、ブログ記事タイトル上にある前後リンクは、分かりにくいですが、同一カテゴリーのブログ記事です。

また、ブログ記事に複数カテゴリーを設定している場合は、すべてのカテゴリーの前後リンクも表示します(こんなに表示するのもどうかと思いますが...)。

以下、カスタマイズ方法です。
1.プラグインのダウンロード
Previous and next in category のサイトに進み、「PreviousNextInCategory」のリンクをクリック。
![]()
2.プラグインのインストール
ダウンロードした PreviousNextInCategory.zip を解凍して、PreviousNextInCategory.pl をpluginsディレクトリにアップロードします。
ブログ管理画面より、「システムメニュー」→「プラグイン」で「PreviousNextInCategory.pl」が表示されればインストール完了です。

3.プライマリカテゴリーに属するブログ記事のみを表示する場合
ブログ記事アーカイブの任意の位置に下記のサブテンプレートを設定してください。
<MTEntryPreviousInCategory>
<a href="<$MTEntryPermalink$>">« <$MTEntryTitle$></a> |
</MTEntryPreviousInCategory>
<a href="<$MTEntryPermalink archive_type="Category"$>"><$MTEntryCategory$></a>
<MTEntryNextInCategory>
| <a href="<$MTEntryPermalink$>"><$MTEntryTitle$> »</a>
</MTEntryNextInCategory>
ブログ記事アーカイブを再構築すれば、冒頭のように、同一カテゴリーの前後記事リンクが表示されます。
4.ブログ記事に登録されているすべてのカテゴリーに属するブログ記事を表示する場合
PreviousNextInCategory.plを任意のエディタで開き、
:
sub _hdlr_entry_previous_in_category {
my($ctx, $args, $cond) = @_;
my $e = $ctx->stash('entry')
or return $ctx->_no_entry_error('MTEntryPrevious');
my $cat = $e->category
or return '';
my $prev = $e->previous(1);
:
sub _hdlr_entry_next_in_category {
my($ctx, $args, $cond) = @_;
my $e = $ctx->stash('entry')
or return $ctx->_no_entry_error('MTEntryNext');
my $cat = $e->category
or return '';
my $next = $e->next(1);
:
の部分に下記の青色の行を追加します。
:
sub _hdlr_entry_previous_in_category {
my($ctx, $args, $cond) = @_;
my $e = $ctx->stash('entry')
or return $ctx->_no_entry_error('MTEntryPrevious');
my $cat = $e->category
or return '';
if($ctx->stash('category') ne '') {
$cat = $ctx->stash('category');
}
my $prev = $e->previous(1);
:
sub _hdlr_entry_next_in_category {
my($ctx, $args, $cond) = @_;
my $e = $ctx->stash('entry')
or return $ctx->_no_entry_error('MTEntryNext');
my $cat = $e->category
or return '';
if($ctx->stash('category') ne '') {
$cat = $ctx->stash('category');
}
my $next = $e->next(1);
:
ブログ記事アーカイブの任意の位置に下記のサブテンプレートを設定してください。
<MTEntryCategories>
<p>
<MTEntryPreviousInCategory>
<a href="<$MTEntryPermalink$>">« <$MTEntryTitle$></a> |
</MTEntryPreviousInCategory>
<a href="<$MTCategoryArchiveLink$>"><$MTCategoryLabel$></a>
<MTEntryNextInCategory>
| <a href="<$MTEntryPermalink$>"><$MTEntryTitle$> »</a>
</MTEntryNextInCategory>
</p>
</MTEntryCategories>
ブログ記事アーカイブを再構築すれば、ブログ記事が属する全カテゴリーの前後記事リンクが表示されます。
5.前後記事の再構築をする
上記の設定だけでは、ブログ記事投稿時に同一カテゴリーの前後記事が再構築されないという問題があります。
ということで、一応、MT4対応のプラグインを作ってみました。
元プラグインをかなり改変してしまったので、上記のファイルをダウンロードしたら、元プラグインにある、
_hdlr_entry_previous_in_category
_hdlr_entry_next_in_category
を埋め込んでください(複数カテゴリーに対応させる場合は4項のカスタマイズも行ってください)。
具体的な作業は、ダウンロードしたファイルの最後の方に簡単な説明を入れてますので、それを読んでください。
複数のカテゴリーを設定したブログ記事でも、前後リンクのブログ記事はすべて再構築されます。
なお、再構築は同じカテゴリーのブログ記事を検索するという、元記事のロジックをそのまま使わせてもらってますが、パフォーマンスの問題を解消する改善策がありましたらご教示ください。
6.参考記事
このエントリーは下記の記事を参考にさせていただきました。ありがとうございました。
カテゴリーアーカイブのサブカテゴリーリストに、親カテゴリーとその子カテゴリーを表示する
Movable Type のカテゴリーアーカイブに表示しているサブカテゴリーリストにおいて、自カテゴリーと、その親カテゴリーに属するカテゴリーを表示するカスタマイズです。
具体例を説明します。例えば、ブログのカテゴリーが、
cat1
├ cat1-1
├ cat1-2
└ cat1-3
cat2
├ cat2-1
├ cat2-2
└ cat2-3
cat3
├ cat3-1
├ cat3-2
└ cat3-3
となっていると仮定します。
cat1-1 のカテゴリーアーカイブを表示した時、サブカテゴリーリストには、
cat1
├ cat1-1
├ cat1-2
└ cat1-3
のみを表示します。また、cat2-2 のカテゴリーアーカイブを表示した時、サブカテゴリーリストには、
cat2
├ cat2-1
├ cat2-2
└ cat2-3
のみを表示します。
1.サブカテゴリーのアーカイブで親カテゴリーとそのサブカテゴリーを表示する
次のサブテンプレートを任意の位置に設定して、再構築してください。
<MTParentCategory>
<MTSubCategories include_current="1">
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</MTParentCategory>
このサブテンプレートは、親カテゴリーでは何も表示されません。親カテゴリーは、一番外側の MTParentCategory タグの実行条件にマッチしない(親カテゴリーに親カテゴリーが存在しない)ためです。
2.親カテゴリーでも同じように表示する
親カテゴリーである cat1 のカテゴリーアーカイブを表示した時、サブカテゴリーリストに
cat1
├ cat1-1
├ cat1-2
└ cat1-3
とする場合は、先のサブテンプレートに下記の青色部分を追加します。
<MTParentCategory>
<MTSubCategories include_current="1">
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</MTParentCategory>
<MTHasNoParentCategory>
<MTSubCategories include_current="1">
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</MTHasNoParentCategory>
ちなみに上記のリストでは、MTSubCategories が2ヶ所出現し、その内容は全く同じです(赤色部分)。
<MTParentCategory>
<MTSubCategories include_current="1">
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</MTParentCategory>
<MTHasNoParentCategory>
<MTSubCategories include_current="1">
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</MTHasNoParentCategory>
次のように MTSetVarTemplate タグを使って丸めておけば、サブテンプレートの重複したマークアップを解消できます。
<mt:setvartemplate name="subcategorylist">
<MTSubCategories include_current="1">
<MTSubCatIsFirst><ul></MTSubCatIsFirst>
<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a> [<$MTCategoryCount$>]
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>
<MTSubCatsRecurse>
</li>
<MTSubCatIsLast></ul></MTSubCatIsLast>
</MTSubCategories>
</mt:setvartemplate>
<MTParentCategory>
<mt:getvar name="subcategorylist">
</MTParentCategory>
<MTHasNoParentCategory>
<mt:getvar name="subcategorylist">
</MTHasNoParentCategory>
3.カテゴリーアーカイブ以外でこのサブテンプレートを表示させない対処
いずれの方法も、リストの一番外側は、
<MTIf name="category_archive">
:
</MTIf>
で括っておけば、他のアーカイブで表示されずに済みます。
ブログ記事に同一カテゴリーのブログ記事リストを表示(MT4版・改)
「ブログ記事に同一カテゴリーのブログ記事リストを表示(MT4版)」や、これまでの似たようなカスタマイズでは、次の問題あることが判明しました。
1.問題点
異なる親カテゴリーに同名のサブカテゴリーがある場合、対応できない。
具体的には、次のようなカテゴリー構成を想定します。
cat-A
├ cat-1
└ cat-2
cat-B
├ cat-1
└ cat-2
この構成で「ブログ記事に同一カテゴリーのブログ記事リストを表示(MT4版)」を行うと、cat-A/cat-1 に属するブログ記事と、cat-B/cat-1 に属するブログ記事は「同一カテゴリーのブログ記事リスト」とみなされてしまいます。
2.原因
「同一カテゴリーのブログ記事リスト」のキー情報として、MTEntryCategory という、ブログ記事に属するメインカテゴリー名のみ使っており、カテゴリーの親カテゴリーまで含めた情報やID番号でサーチしていないためです。
こうなった経緯は、そもそも、Movable Type 3 の途中まで「サブカテゴリー」という概念が存在しませんでした。つまり、親カテゴリーしか作れなかったため、同名のカテゴリーの存在が許されず、これまでのサブテンプレートを使えば「同一カテゴリーのブログ記事リスト」を実現できた、という訳です。
3.対処
3.1 EntryCategoryID プラグインを使う
「EntryCategoryID プラグイン」を使い、ブログ記事のメインカテゴリーのID番号と、ブログ記事リストのカテゴリーIDを比較し、同一カテゴリーID のブログ記事のみリスティングします。
<mt:setvarblock name="entrycategoryid"><$MTEntryCategoryID$></mt:setvarblock>
<dt class="sidetitle">
Entries of this Category
</dt>
<dd class="side">
<ul>
<MTCategories>
<mt:setvarblock name="currentcategoryid"><$MTCategoryID$></mt:setvarblock>
<mt:if name="currentcategoryid" eq="$entrycategoryid">
<MTEntries>
<li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
</MTEntries>
</mt:if>
</MTCategories>
</ul>
</dd>
3.2 MTParentCategories タグを使う(その1)
これは後から気がついたのですが、MTParentCategories タグを使い、ブログ記事のメインカテゴリーの親カテゴリーを取得すれば、3.1項と同じことができます。
<MTParentCategories glue="/" setvar="entrycategories"><$MTCategoryLabel$></MTParentCategories>
<dt class="sidetitle">
Entries of this Category
</dt>
<dd class="side">
<ul>
<MTCategories>
<MTParentCategories glue="/" setvar="currententrycategories"><$MTCategoryLabel$></MTParentCategories>
<mt:if name="currententrycategories" eq="$entrycategories">
<MTEntries>
<li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
</MTEntries>
</mt:if>
</MTCategories>
</ul>
</dd>
MTParentCategories のカテゴリーのセパレータには "/"、また MTSetvarBlock タグの代わりに setvar モディファイアを利用しています。
3.3 MTParentCategories タグを使う(その2)
こちらは、MTEntries タグに category モディファイアを与えて、とりあえず自カテゴリーで絞り込んでから親カテゴリーと比較します。
<mt:setvarblock name="entrycategory"><$MTEntryCategory$></mt:setvarblock>
<MTParentCategories glue="/" setvar="entrycategories"><$MTCategoryLabel$></MTParentCategories>
<dt class="sidetitle">
Entries of this Category
</dt>
<dd class="side">
<ul>
<MTEntries category="$entrycategory">
<MTParentCategories glue="/" setvar="currententrycategories"><$MTCategoryLabel$></MTParentCategories>
<mt:if name="currententrycategories" eq="$entrycategories">
<li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
</mt:if>
</MTEntries>
</ul>
</dd>
2008.02.25
3.3項を追加しました。
Movable Type 4 でカテゴリー別にデザインを切り替える方法(その3)
Movable Type 4 でカテゴリー別にデザインを切り替える方法を、何回かに分けて紹介します。
1.MTIfCategory タグブロック内のサブテンプレートをモジュール化する
カテゴリーアーカイブのデザインを変更する2つめの方法で、MTIfCategory タグブロック内にサブテンプレートをベタ書きするのではなく、MTInclude タグを使います。
カテゴリー1~3
<MTIfCategory name="カテゴリー1">
<$MTInclude module="カテゴリー1"$>
</MTIfCategory>
<MTIfCategory name="カテゴリー2">
<$MTInclude module="カテゴリー2"$>
</MTIfCategory>
<MTIfCategory name="カテゴリー3">
<$MTInclude module="カテゴリー3"$>
</MTIfCategory>
こうすることにより、カテゴリーアーカイブ本体では「どのカテゴリーにどのテンプレートを割り当てるか」という制御に徹することができ、テンプレート全体の見通しがよくなります。
汎用的なデザインを与えたいカテゴリー4~6を新たに追加する場合は、次のようにします。
<MTIfCategory name="カテゴリー1">
<$MTInclude module="カテゴリー1"$>
<MTElse>
<MTIfCategory name="カテゴリー2">
<$MTInclude module="カテゴリー2"$>
<MTElse>
<MTIfCategory name="カテゴリー3">
<$MTInclude module="カテゴリー3"$>
<MTElse>
<$MTInclude module="カテゴリーその他"$>
</MTIfCategory>
</MTIfCategory>
</MTIfCategory>
最初の MTIfCategory タグでカテゴリー1であるかの判定をし、そうでなければ MTElse を実行して、次の MTIfCategory タグでカテゴリー2であるかの判定をします。その繰り返しで、最後のカテゴリー判定にマッチしなかったカテゴリーには一番最後の MTElse タグの内容、つまりデフォルトとなるデザインのテンプレートモジュールを呼び出します。
2.MTIfCategory タグを除去して、モジュール化をさらに簡素化する
さて、すでにお気づきの方もいらっしゃると思いますが、最初のリストは、カテゴリーを識別するキーさえ取得できれば、実は以下の1行で済みます。
<$MTInclude module="カテゴリーを識別するキー"$>
「カテゴリーを識別するためのキー」として、次のようにカテゴリー名を使ってみます。カテゴリー名は、MTInclude タグを実行する前に、MTSetVarBlock タグを使って変数に設定し、変数名をmoduleモディファイアに与えれば、ダイナミックにカテゴリー名を設定することができます。
<mt:setvarblock name="category_name"><$MTCategoryLabel$></mt:setvarblock>
<$MTInclude module="$category_name"$>
これで、このアーカイブが「カテゴリー1」の再構築を行うときには変数 category_name には「カテゴリー1」が、「カテゴリー2」の再構築を行うときには変数 category_name には「カテゴリー2」…という具合に設定され、それぞれ「カテゴリー1」「カテゴリー2」…という名前のテンプレートモジュールを呼び出します。
注意するのは、変数category_nameをmoduleモディファイア(というか、nameモディファイア以外)で使う場合は、変数名の前に大抵「$」をつけておく、ということです。
3.MTIf タグを使ってデフォルトデザインの条件分岐をつける
2つめのリストのように、デフォルトのデザインと振り分けたい場合は、さらに MTIf タグと MTCategoryDescription タグで制御します。この方法は SYSTEM STUDIO さんよりアイデア頂きました。ありがとうございました。
<mt:setvarblock name="category_description"><$MTCategoryDescription$></mt:setvarblock>
<mt:if name="category_description">
<$MTInclude module="$category_description"$>
<mt:else>
<$MTInclude module="デフォルト"$>
<mt:if>
このリストを使う前準備として、各カテゴリーの「カテゴリーの説明」欄に、呼び出したいモジュール名を設定しておきます。デフォルトデザインのモジュールを呼び出したいときには、「カテゴリーの説明」欄には何も設定しません。
そうすれば、MTIf タグの判定で「カテゴリーの説明」欄に記入されている場合に、「カテゴリーの説明」欄に設定された名前のテンプレートモジュールを呼び出します。「カテゴリーの説明」欄に記入していない場合は、「デフォルト」という名前のテンプレートモジュールを呼び出します。
なお、前回もお伝えしたとおり、「カテゴリーの説明」欄を使うよりも、カスタムフィールドを利用した方が妥当に思われます。
Movable Type 4 でカテゴリー別にデザインを切り替える方法(その2)
Movable Type 4 でカテゴリー別にデザインを切り替える方法を、何回かに分けて紹介します。
1.ひとつのアーカイブテンプレートでカテゴリーを分割する
カテゴリーアーカイブのデザインを変更する2つめの方法は、アーカイブテンプレートの中で MTIfCategory タグを使います。MTIfCategory タグの name モディファイアには、カテゴリー名が重複しないように設定します。
カテゴリー1~3
<MTIfCategory name="カテゴリー1">
:
(カテゴリー1用のテンプレート)
:
</MTIfCategory>
<MTIfCategory name="カテゴリー2">
:
(カテゴリー2用のテンプレート)
:
</MTIfCategory>
<MTIfCategory name="カテゴリー3">
:
(カテゴリー3用のテンプレート)
:
</MTIfCategory>
この方法には、次のような特徴があります。
- カテゴリーの振り分け処理が可能
- 基本的にパスは一意に決まる
- 優先の制約がない
ひとつのアーカイブテンプレートにまとめる一番のメリットは、あるいくつかのカテゴリーには特殊なデザインを与え、そうでないものについては汎用的なデザインを適用できることです。
「その1」の方法では、アーカイブテンプレートをカテゴリーごとに与えているため、そのような制御ができなくなります。
例えば、冒頭のサブテンプレートに、汎用的なデザインを使いたいカテゴリー4~6を新たに追加する場合、最初に示したサブテンプレートでは、カテゴリー4~6を個別に指定する必要がありますが、次のように変更すれば、一括した指定が可能です。
<MTIfCategory name="カテゴリー1">
:
(カテゴリー1用のテンプレート)
:
<MTElse>
<MTIfCategory name="カテゴリー2">
:
(カテゴリー2用のテンプレート)
:
<MTElse>
<MTIfCategory name="カテゴリー3">
:
(カテゴリー3用のテンプレート)
:
<MTElse>
:
(カテゴリー4~6用のテンプレート)
:
</MTIfCategory>
</MTIfCategory>
</MTIfCategory>
最初の MTIfCategory タグでカテゴリー1であるかの判定をし、そうでなければ MTElse を実行して、次の MTIfCategory タグでカテゴリー2であるかの判定をします。その繰り返しで、最後のカテゴリー判定にマッチしなかったカテゴリーには一番最後の MTElse タグの内容、つまりデフォルトとなるデザインを適用します。
次の設定は誤りです。
<MTIfCategory name="カテゴリー1">
:
(カテゴリー1用のテンプレート)
:
</MTIfCategory>
<MTIfCategory name="カテゴリー2">
:
(カテゴリー2用のテンプレート)
:
</MTIfCategory>
<MTIfCategory name="カテゴリー3">
:
(カテゴリー3用のテンプレート)
:
<MTElse>
:
(カテゴリー4~6用のテンプレート)
:
</MTIfCategory>
理由は、「カテゴリー4~6用のテンプレート」と書かれた部分にはカテゴリー1とカテゴリー2が含まれるからです。
また、この方法では基本的に全てのカテゴリーに共通のパスを与えますが、テンプレートタグを用いることでカテゴリー別に異なるパスを与えることもできます(これについては別の機会に)。またカテゴリー用アーカイブがひとつであるため、「優先」の問題も回避できます。
2.スタイルシートについて
ここでは次の方法が考えられます。
まず、head 要素が、各カテゴリーのサブテンプレートに含まれているのであれば、head 要素内にカテゴリー用のスタイルシートを呼び出す link 要素をそのまま記述します。
すべてのカテゴリーが共通で head 要素をテンプレートモジュールとして呼び出している場合は、MTIfCategory タグブロック内に次のような MTSetVar タグを記述します。
<MTIfCategory name="cat1">
<mt:setvar name="style" value="[カテゴリー1用スタイルシートのファイル名]">
</MTIfCategory>
<MTIfCategory name="cat2">
<mt:setvar name="style" value="[カテゴリー2用スタイルシートのファイル名]">
</MTIfCategory>
<MTIfCategory name="cat3">
<mt:setvar name="style" value="[カテゴリー3用スタイルシートのファイル名]">
</MTIfCategory>
<$MTInclude module="ヘッダー"$>
<MTIfCategory name="カテゴリー1">
:
(カテゴリー1用のテンプレート)
:
汎用的なカテゴリー用のスタイルシートを作りたい場合は、次のようにします。
<MTIfCategory name="cat1">
<mt:setvar name="style" value="[カテゴリー1用スタイルシートのファイル名]">
<MTElse>
<MTIfCategory name="cat2">
<mt:setvar name="style" value="[カテゴリー2用スタイルシートのファイル名]">
<MTElse>
<MTIfCategory name="cat3">
<mt:setvar name="style" value="[カテゴリー3用スタイルシートのファイル名]">
<MTElse>
<mt:setvar name="style" value="[カテゴリー4~6用スタイルシートのファイル名]">
</MTIfCategory>
</MTIfCategory>
</MTIfCategory>
<$MTInclude module="ヘッダー"$>
<MTIfCategory name="カテゴリー1">
:
(カテゴリー1用のテンプレート)
:
そして、「ヘッダー」モジュールには次のように記述しておきます。
<mt:if name="category_archive">
<link rel="stylesheet" href="<$MTBlogURL$><$mt:getvar name="style"$>" type="text/css" title="<$MTCategoryLabel encode_html="1"$>" media="screen,tv" />
</mt:if>
または、MTCategoryDescription タグにスタイルシートのファイル名(下のサンプルでは拡張子なし)を設定しておき、「ヘッダー」モジュールだけで呼び出せる方法もあります。
<mt:if name="category_archive">
<link rel="stylesheet" href="<$MTBlogURL$><$MTCategoryDescription$>.css" type="text/css" title="<$MTCategoryLabel encode_html="1"$>" media="screen,tv" />
</mt:if>
異なるカテゴリーで同じデザインを適用したい場合は、MTCategoryDescription タグに該当する「カテゴリーの説明」欄に同じ名称を記述しておきます。
なお、「カテゴリーの説明」よりもカスタムフィールドを使う方が、用途が明確になってよりいいでしょう。
- Movable Type 4 でカテゴリー別にデザインを切り替える方法(その1)
- Movable Type 4 でカテゴリー別にデザインを切り替える方法(その2)
- Movable Type 4 でカテゴリー別にデザインを切り替える方法(その3)
Movable Type 4 でカテゴリー別にデザインを切り替える方法(その1)
Movable Type 4 でカテゴリー別にデザインを切り替える方法を、何回かに分けて紹介します。
1.カテゴリー別にアーカイブテンプレートを独立させる
カテゴリーアーカイブのデザインを変更するために、カテゴリー別に複数のアーカイブテンプレートを作る方法があります。その際、カテゴリーアーカイブテンプレート全体を MTIfCategory タグで括ります。MTIfCategory タグの name モディファイアには、カテゴリー名が重複しないように設定します。
カテゴリー1
<MTIfCategory name="カテゴリー1">
:
(カテゴリー1用のテンプレート)
:
</MTIfCategory>
カテゴリー2
<MTIfCategory name="カテゴリー2">
:
(カテゴリー2用のテンプレート)
:
</MTIfCategory>
カテゴリー3
<MTIfCategory name="カテゴリー3">
:
(カテゴリー3用のテンプレート)
:
</MTIfCategory>
この方法には、次のような特徴があります。
- カテゴリーアーカイブテンプレートの独立性
- カテゴリー別にパスを変更できる
- カテゴリー別に異なるパスを設定すると「優先」の制約が発生する
まず、カテゴリーアーカイブテンプレートを独立させ、テンプレートとカテゴリーを1:1の対応にするので、下のように編集対象のカテゴリーが視覚的に分かりやすくなるというメリットがあります。また、テンプレートの内容にもよりますが、この方法であれば、Movable Type 4 の制御系タグをほとんど使わずにすむかもしれません。

また、カテゴリー別に異なるパスを与えたい場合、この方法以外に選択の余地はありません。テンプレートタグをパス欄に設定すれば個別に設定することも可能です。
最後の「カテゴリー別に異なるパスを設定すると「優先」の制約が発生する」の意味は、まず、同一アーカイブ種別のテンプレートを複数作成すると、「優先」の問題が発生します。「優先」とは、他のページからあるアーカイブ種別のアーカイブにリンクする場合のリンク先を決めるためのもので、優先にするテンプレートにはチェックをつけます。

例えば、カテゴリー1・カテゴリー2・カテゴリー3用のアーカイブテンプレートを、それぞれ別のアーカイブテンプレートで作成した場合、どれかひとつのアーカイブテンプレートが「優先」に、残りが「非優先」になります。
もし、カテゴリー別にパスを変更した場合、メインページなどでカテゴリーリストを、MTTopLevelCategories タグで表示すると、「優先」が設定されたカテゴリーのパスで表示されるので、非優先のカテゴリーアーカイブページはデッドリンクになります。
ただし、全てのカテゴリーアーカイブが同じパスであれば、非優先カテゴリーアーカイブへのリンクも、優先カテゴリーアーカイブで生成されたリンクが利用できます(たまたまそうなるだけであり、手法としては適切ではないかもしれません)。
2.スタイルシートについて
ここでは2つの方法が考えられます。
まず、head 要素が、独立させたカテゴリーアーカイブにそれぞれ含まれているのであれば、head 要素内にカテゴリー用のスタイルシートを呼び出す link 要素をそのまま記述します。これが一番シンプルな方法です。
もうひとつは、head 要素をテンプレートモジュールとして呼び出している場合は、MTIfCategory タグブロック内に次のような MTSetVar タグを記述します。
<MTIfCategory name="cat1">
<mt:setvar name="style" value="[カテゴリー用スタイルシートのファイル名]">
<$MTInclude module="ヘッダー"$>
:
</MTIfCategory>
そして、「ヘッダー」モジュールには次のように記述します。
<mt:if name="category_archive">
<link rel="stylesheet" href="<$MTBlogURL$><$mt:getvar name="style"$>" type="text/css" title="<$MTCategoryLabel encode_html="1"$>" media="screen,tv" />
</mt:if>
または、MTCategoryDescription タグにスタイルシートのファイル名(下のサンプルでは拡張子なし)を設定しておき、「ヘッダー」モジュールだけで呼び出せる方法もあります。
<mt:if name="category_archive">
<link rel="stylesheet" href="<$MTBlogURL$><$MTCategoryDescription$>.css" type="text/css" title="<$MTCategoryLabel encode_html="1"$>" media="screen,tv" />
</mt:if>
異なるカテゴリーで同じデザインを適用したい場合は、MTCategoryDescription タグに同じ名称を記述しておきます。
後者の方法は、他のカテゴリー分割方法でも共通に使えます。
2008.02.20
カテゴリーパスの記述を一部修正しました。
- Movable Type 4 でカテゴリー別にデザインを切り替える方法(その1)
- Movable Type 4 でカテゴリー別にデザインを切り替える方法(その2)
- Movable Type 4 でカテゴリー別にデザインを切り替える方法(その3)
Movable Type 4 のカテゴリーアーカイブで全てのブログ記事を表示する
Movable Type 4 デフォルトテンプレートでのカテゴリーアーカイブでは、そのカテゴリーのブログ記事が全て表示されない仕組みになっています。
これは、カテゴリーアーカイブの表示記事数を絞る代わりに、「月別カテゴリーアーカイブ」を併用して、カテゴリーアーカイブの分割ページとして賄うようにしているためです。
こうすることで、カテゴリーアーカイブの記事数が増大しても、カテゴリーアーカイブをページ分割等で表示記事数を絞る必要がなくなります。
本エントリーでは、カテゴリーアーカイブで表示記事数がメインページと同じになる仕組みと、それを解除する方法等について解説します。
1.カテゴリーアーカイブで表示記事数が絞られる仕組み
仕組みは簡単で、デフォルトテンプレートであれば、「デザイン」→「テンプレート」→「アーカイブテンプレート」→「ブログ記事リスト」の MTEntries タグに limit モディファイアを適用されていると思います。このモディファイアの値に "auto" が設定されていれば、アーカイブでの表示記事数が「設定」→「ブログの設定」→「ブログ記事」→「ブログ記事の表示数」の設定が適用されます。つまりメインページと同じ表示になります。
:
<MTIf name="datebased_archive">
<MTEntries>
<$MTEntryTrackbackData$>
<$MTInclude module="ブログ記事の概要"$>
</MTEntries>
<MTElse>
<MTEntries limit="auto">
<$MTEntryTrackbackData$>
<$MTInclude module="ブログ記事の概要"$>
</MTEntries>
</MTIf>
:
上のリストは、次のように表示するアーカイブを振り分けています。
<MTIf name="datebased_archive">
:
(日付アーカイブ)
:
<MTElse>
:
(カテゴリーアーカイブ)
:
</MTIf>
limit モディファイアは lastn モディファイアと似たような動作を行ないます。
2.カテゴリーアーカイブで記事をすべて表示する
「デザイン」→「テンプレート」→「アーカイブテンプレート」→「ブログ記事リスト」で、limit モディファイアを削除すれば、カテゴリーアーカイブで記事をすべて表示できます(下)。
:
<MTIf name="datebased_archive">
<MTEntries>
<$MTEntryTrackbackData$>
<$MTInclude module="ブログ記事の概要"$>
</MTEntries>
<MTElse>
<MTEntries>
<$MTEntryTrackbackData$>
<$MTInclude module="ブログ記事の概要"$>
</MTEntries>
</MTIf>
:
ただし、この方法では、記事数が増えるにしたがってファイルサイズも増大するので、日付カテゴリアーカイブとの併用が望ましいです。
3.月別カテゴリーアーカイブリストを表示する
当ブログの配布テンプレートではサイドバーに月別カテゴリーアーカイブのリストが表示されないので(過去のバージョンで一部表示されるものもあります)、下記のリストを「サイドバー」テンプレートに貼り付けておけば、月別カテゴリーアーカイブにリンクさせることができます(この点についてはいずれ修正します)。
<MTIf name="module_category-monthly_archives">
<MTIfArchiveTypeEnabled archive_type="Category-Monthly">
<dt class="sidetitle">
Monthly <$MTCategoryLabel$>
</dt>
<dd class="side">
<ul>
<MTArchiveList archive_type="Category-Monthly">
<li><a href="<$MTArchiveLink$>"><$MTArchiveTitle$></a> [<$MTArchiveCount$>]</li>
</MTArchiveList>
</ul>
</dd>
</MTIfArchiveTypeEnabled>
</MTIf>
4.関連記事
dtree のサブカテゴリーリストにブログ記事タイトルを表示する for Movable Type
以前ご紹介した、「dTree によるサブカテゴリーリスト for Movable Type」で、ブログ記事タイトルを表示するカスタマイズをご紹介します。
dTree とは、エクスプローラー風のツリー表示用スクリプトです。下記のサンプルで動作をご確認ください。
本エントリーのカスタマイズを行うことで、下のスクリーンショットのように、各カテゴリー配下に属するブログ記事タイトルを表示させることができます。

以下、サブカテゴリーリストにブログ記事タイトルを表示するカスタマイズです。なお、この記事の5項の設定を行う前に、「dTree によるサブカテゴリーリスト for Movable Type」の4項までを設定しておいてください。
5.dTree サブカテゴリーリスト表示用タグ設定
テンプレートで、サブカテゴリーリストを表示したい位置に下記のタグを設定してください。
表示用タグは PHP 版と JavaScript 版、MTタグ版を用意しました。表示される結果はどれも同じです。
5.1 PHP版
このタグを設定する場合、PHP化を行っていることが前提です。
<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'SubCategories','javascript: void(0);');
<?php $cat_number = 0; $level = 0; $tree = array(); ?>
<MTTopLevelCategories>
<?php $tree[$level] = ++$cat_number; if(!$level) { ?>
d.add(<?php echo $cat_number ?>, 0,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { if(!$tree[$level - 1]) { ?>
d.add(<?php echo $cat_number ?>, 1,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { ?>
d.add(<?php echo $cat_number ?>, <?php echo $tree[$level - 1] ?>,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php }} ?>
<MTEntries>
<MTEntriesHeader>
<?php $level++; ?>
</MTEntriesHeader>
<?php $cat_number++; ?>
d.add(<?php echo $cat_number ?>, <?php echo $tree[$level - 1] ?>,'<$MTEntryTitle encode_php="1"$>','<$MTEntryPermalink$>');
<MTEntriesFooter>
<?php $level--; ?>
</MTEntriesFooter>
</MTEntries>
<?php $level++; ?>
<MTSubCatsRecurse>
<?php $level--; ?>
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>
5.2 JavaScript 版
<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1, 'SubCategories','javascript: void(0);');
var cat_number = 0;
var level = 0;
var link = new Array();
<MTTopLevelCategories>
link[level] = ++cat_number;
if(!level) {
d.add(cat_number, 0,'<$MTCategoryLabel encode_js="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
} else {
if(!link[level - 1]) {
d.add(cat_number, 1,'<$MTCategoryLabel encode_js="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
} else {
d.add(cat_number, link[level - 1],'<$MTCategoryLabel encode_js="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
}
}
<MTEntries>
<MTEntriesHeader>
level++;
</MTEntriesHeader>
cat_number++;
d.add(cat_number, link[level - 1],'<$MTEntryTitle encode_js="1"$>','<$MTEntryPermalink$>');
<MTEntriesFooter>
level--;
</MTEntriesFooter>
</MTEntries>
level++;
<MTSubCatsRecurse>
level--;
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>
5.3 テンプレートタグ版(MT4.1 以上のみ対応)
<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'Categories','javascript: void(0);');
<$mt:setvar name="cat_number" value="1"$>
<$mt:setvar name="level" value="1"$>
<MTTopLevelCategories>
<$mt:setvar name="cat_number" op="++"$>
<$mt:setvar name="tree[$level]" value="$cat_number"$>
<mt:if name="level" eq="1">
d.add(<$mt:getvar name="cat_number" op="--"$>, 0,'<$MTCategoryLabel escape="html"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<mt:else>
d.add(<$mt:getvar name="cat_number" op="--"$>, <$mt:setvar name="tmp" value="$level"$><$mt:setvar name="tmp" op="--"$><$mt:getvar name="tree[$tmp]" op="--"$>,'<$MTCategoryLabel escape="html"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
</mt:if>
<MTEntries>
<MTEntriesHeader>
<$mt:setvar name="level" op="++"$>
</MTEntriesHeader>
<$mt:setvar name="cat_number" op="++"$>
d.add(<$mt:getvar name="cat_number" op="--"$>, <$mt:setvar name="tmp" value="$level"$><$mt:setvar name="tmp" op="--"$><$mt:getvar name="tree[$tmp]" op="--"$>,'<$MTEntryTitle escape="html"$>','<$MTEntryPermalink$>');
<MTEntriesFooter>
<$mt:setvar name="level" op="--"$>
</MTEntriesFooter>
</MTEntries>
<$mt:setvar name="level" op="++"$>
<$MTSubCatsRecurse$>
<$mt:setvar name="level" op="--"$>
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>
以上です。
2007.12.28
MT3.x でパーマリンクが正常に生成されない不具合を修正しました(MTEntryPermaLink を MTEntryPermalink に修正)。
Movable Type 4.1/MTOS のネイティブタグで dTree を実装する
Movable Type 4.1/MTOS で変数の算術演算子と配列およびハッシュが実装されたことで、PHPあるいはJavaScriptとの組み合わせが必要だった処理が、ネイティブなタグのみで実装可能になりました。
全てのコードについて移植が可能であるかどうかは不明ですが、どの程度の威力があるか検証してみたかったので、サンプルとして、以前紹介した dTree のカスタマイズについてテンプレートタグで実装してみました。
1.dTree について
機能や設定方法は下記の記事を参照願います(実際にご利用になる場合、この記事の4項までの設定が必要です)。
で、元記事で紹介したPHP版のスクリプトは下記の通りです(若干直しました)。
<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'Categories','javascript: void(0);');
<?php $cat_number = 0; $level = 0; $tree = array(); ?>
<MTTopLevelCategories>
<?php $tree[$level] = ++$cat_number; if(!$level) { ?>
d.add(<?php echo $cat_number ?>, 0,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { ?>
d.add(<?php echo $cat_number ?>, <?php echo $tree[$level - 1] ?>,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } $level++; ?>
<MTSubCatsRecurse max_depth="3">
<?php $level--; ?>
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>
再掲になりますが、dTree によるサブカテゴリーリストの完成イメージは次の通りです。

この表示を行うための JavaScript は次の内容になっています(上記のPHPスクリプトから生成されたものです)。
<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'Categories','javascript: void(0);');
d.add(1, 0,'test1','http://.../test/');
d.add(2, 1,'test1-1','http://.../test/test11/');
d.add(3, 2,'test1-1-1','http://.../test/test11/test111/');
d.add(4, 2,'test1-1-2','http://.../test/test11/test112/');
d.add(5, 1,'test1-2','http://.../test/test12/');
d.add(6, 5,'test1-2-1','http://.../test/test12/test121/');
d.add(7, 5,'test1-2-2','http://.../test/test12/test122/');
d.add(8, 0,'test2','http://.../test2/');
d.add(9, 8,'test2-1','http://.../test2/test21/');
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>
スクリーンショットと JavaScript(のカテゴリー)の対応はなんとなくお分かりになると思いますが、
d.add(...)
の行で、カテゴリー部分を表示させています。
本エントリーでは、Movable Type のネイティブタグのみで、このカテゴリーを表示する部分の JavaScript を生成します。
2.dTree のカテゴリー表示部分のフォーマット
先程も簡単に紹介しましたが、JavaScript でカテゴリーを表示する部分は add 関数がキモとなっており、関数のパラメータは、
d.add([*1],[*2],[カテゴリー名],[カテゴリーのURL *3]);
- *1:カテゴリーに一意に割り当てられたdTree用のカテゴリー番号
- *2:そのカテゴリーが属する親カテゴリーの番号
"0"はdTreeのルートに属する場合(=最上位のカテゴリー) - *3:dTreeの生成するa要素のhref属性になります。
となっています。
上記の add 関数部分を、サブカテゴリーリストを出力するサブテンプレートを応用して作成します。以下、add 関数の各パラメータをどのようなロジックで作成するかという解説を交えながら、ネイティブなテンプレートを組み立てていきます。
3.各パラメータ用のデータ生成方法
3.1 第1パラメータ用のデータ生成
第1パラメータはカテゴリーに番号を順に付与していけば良いだけので、リスト1のように、
リスト1
<$mt:setvar name="cat_number" value="1"$>
<MTTopLevelCategories>
<$mt:setvar name="cat_number" op="++"$>
d.add(<$mt:getvar name="cat_number"$>,~略~);
<$MTSubCatsRecurse$>
</MTTopLevelCategories>
とすれば良いことが分かります。
1行目でカテゴリー番号保持用の変数(cat_number)を1で初期化し、MTTopLevelCategories タグのループ内でインクリメントしていきま