MTParentCategories タグを入れ子の ul、li 要素で表示する

Movable Type の MTParentCategories タグを入れ子の ul、li 要素で表示してみました。使用用途は少ないかもしれませんが、このブログでは、ブログ記事の下の記事に関する情報として使ってみています(2008/12/15 現在)。

MTParentCategoriesタグを入れ子のul,li要素で表示したイメージ

完成したソース

<mt:SetVarBlock name="thisEntCat"><$mt:EntryCategory$></mt:SetVarBlock>
<mt:SetVar name="count" value="0">
<ul><li class="home"><a href="/blog/" title="トップページへ戻る">ホーム</a><ul><li>
<mt:ParentCategories glue="<ul><li>">
<mt:SetVar name="count" op="+" value="1">
<mt:SetVarBlock name="loopEntCat"><$mt:CategoryLabel$></mt:SetVarBlock>
<mt:If tag="CategoryCount">
<a<mt:If name="loopEntCat" eq="$thisEntCat"> class="current"</mt:If> href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a>
<mt:Else>
<$mt:CategoryLabel$>
</mt:If>
</mt:ParentCategories>

<mt:SubCategories include_current="0" category="$thisEntCat">
<mt:SubCatIsFirst><ul></mt:SubCatIsFirst>
<mt:If tag="CategoryCount">
<li><a href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a><$mt:SubCatsRecurse$></li>
<mt:Else>
<li><$mt:CategoryLabel$><$mt:SubCatsRecurse$></li>
</mt:If>
<mt:SubCatIsLast></ul></mt:SubCatIsLast>
</mt:SubCategories>

<mt:For var="i" from="0" to="$count"></li></ul></mt:For>
</mt:If>

MTParentCategories タグとは

MTParentCategories タグとは、MovableType.jpの「MTParentCategories | テンプレートタグリファレンス」によると次のような働きをするテンプレートタグです。

最上位のカテゴリから現在のカテゴリまでを繰り返して表示するブロックタグです。モディファイア glue により、カテゴリをつなげる文字を指定できます。また、モディファイア exclude_current を指定することで、現在のカテゴリを除外できます。

MTParentCategories タグを入れ子の ul、li 要素にするには

まず単純に、MTParentCategories タグを使って、このブログ記事のカテゴリを出力してみましょう。なお、このブログ記事のカテゴリは次のような 2階層とします。

  • Movable Type
    • テンプレート(ブログ記事はこのカテゴリに属する)

このカテゴリ状態で、次のようなテンプレートを書いた場合の出力結果を見てみます。

<mt:ParentCategories>
<$mt:CategoryLabel$>
</mt:ParentCategories>
【出力結果】

Movable Type

テンプレート

なお、ここでは見やすくするためにテンプレートを改行して書いていますが、上記のとおり、実際に出力されるソースにも余計な改行が入ってしまいますので、テンプレートを書く場合は次のように改行を考えて書いた方が良いかも知れません。

また、以降の説明では、出力結果を分かりやすくするために改行を操作しているので、実際の出力結果の改行の状態とは異なります。

<mt:ParentCategories><$mt:CategoryLabel$>
</mt:ParentCategories>
【出力結果】

Movable Type
テンプレート

さて本題に戻り、ここで入れ子の ul、li 要素を考えてみます。もし仮に上の2つのリストを入れ子にするとなると、次のようになります。

<ul>
 <li>Movable Type
 <ul>
 <li>テンプレート</li>
 </ul></li>
</ul>

良く見ると「 Movable Type 」と「テンプレート」は「 <ul><li> 」で区切られているといえます。ですので、先ほどのテンプレートに、glue モディファイアを付けて「 <ul><li> 」で区切ってみます。

<mt:ParentCategories glue="<ul><li>">
<$mt:CategoryLabel$>
</mt:ParentCategories>
【出力結果】

Movable Type
<ul><li>テンプレート

よし。では ul、li の開始と終了タグも付けてみましょう。

<ul>
<mt:ParentCategories glue="<ul><li>">
<li><$mt:CategoryLabel$></li>
</mt:ParentCategories>
</ul>

一見これで良さそう何ですが、実はそんなに単純ではないんですね。これを出力すると次のようになり、入れ子にもならずエラーです。

<ul>
<li>Movable Type</li>
<ul><li><li>テンプレート</li>
</ul>

どうも繰り返される <li></li> はいらなそうなので取ってみます。でもそれだと <li></li> が足りなくなるのは明らかなので、次のようにしてみます。

<ul><li>
<mt:ParentCategories glue="<ul><li>">
<$mt:CategoryLabel$>
</mt:ParentCategories>
</li></ul>
【出力結果】

<ul>
 <li>Movable Type
 <ul>
 <li>テンプレート</li>
 </ul>

かなりいい感じになってきましたが、</li></ul> が1セット足りないようです。どうやら、リストの数だけ </li></ul> が必要なようなので、変数を使ってリストの数をカウントし、その数だけ </li></ul> を繰り返し出力しましょう。

<mt:SetVar name="count" value="0">
<ul><li>
<mt:ParentCategories glue="<ul><li>">
<mt:SetVar name="count" op="+" value="1">
<$mt:CategoryLabel$>
</mt:ParentCategories>
<mt:For var="i" from="1" to="$count"></li></ul></mt:For>
</mt:If>
【出力結果】

<ul>
 <li>Movable Type
 <ul>
 <li>テンプレート</li>
 </ul></li>
</ul>

最初の SetVar で変数 count を 0 として定義し、二つ目の SetVar で繰り返される数だけ 1ずつ足していきます。つまり、変数「 count = リスト数 」ということになります。最後に MTFor タグにより、そのリスト数分の を出力します。

ここで、サイト全体の階層を明確にするために、最上位の階層であるトップページへ戻るための「ホーム」も追加しましょう。

「ホーム」を追加すると、</li></ul> がもう一つ必要になるので、先ほどは「 1 」から始めていた MTFor タグのループを「 0 」から始めるようにします。

<ul><li class="home"><a href="/blog/" title="トップページへ戻る">ホーム</a>
<ul><li>
<mt:ParentCategories glue="<ul><li>">
<mt:SetVar name="count" op="+" value="1">
<$mt:CategoryLabel$>
</mt:ParentCategories>
<mt:For var="i" from="0" to="$count"></li></ul></mt:For>
【出力結果】

<ul>
 <li class="home"><a href="/blog/" title="トップページへ戻る">ホーム</a>
 <ul>
 <li>Movable Type
 <ul>
 <li>テンプレート</li>
 </ul></li>
 </ul></li>
</ul>

さらに、<mt:If tag="CategoryCount"> を使って、カテゴリにブログ記事がある場合のみ、カテゴリーアーカイブへリンクさせます。そして、変数 thisEntCat と loopEntCat を定義して比較し現在のカテゴリの a要素に「 class="current" 」を付けます。

<mt:SetVarBlock name="thisEntCat"><$mt:EntryCategory$></mt:SetVarBlock>
<mt:SetVar name="count" value="0">
<ul><li class="home"><a href="/blog/" title="トップページへ戻る">ホーム</a><ul><li>
<mt:ParentCategories glue="<ul><li>">
<mt:SetVar name="count" op="+" value="1">
<mt:SetVarBlock name="loopEntCat"><$mt:CategoryLabel$></mt:SetVarBlock>
<mt:If tag="CategoryCount">
<a<mt:If name="loopEntCat" eq="$thisEntCat"> class="current"</mt:If> href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a>
<mt:Else>
<$mt:CategoryLabel$>
</mt:If>
</mt:ParentCategories>
<mt:For var="i" from="0" to="$count"></li></ul></mt:For>
</mt:If>
【出力結果】

<ul>
 <li class="home"><a href="/blog/" title="トップページへ戻る">ホーム</a>
 <ul>
 <li><a href="/blog/movable-type/">Movable Type</a>
 <ul>
 <li><a class="current" href="/blog/movable-type/mt-template/">テンプレート</a></li>
 </ul></li>
 </ul></li>
</ul>

現在のカテゴリにサブカテゴリがある場合

ここまでで、完成のようですが、MTParentCategories タグが出力するのは現在のカテゴリまでです。したがって、現在のカテゴリにサブカテゴリが存在する場合、次のように MTSubCategoriesタグを使用して、MTParentCategories タグでは出力しきれないカテゴリを出力します。

MTSubCategories タグにモディファイア include_current="0" をつけて、現在のカテゴリは含めないのがポイントです。

<mt:SetVarBlock name="thisEntCat"><$mt:EntryCategory$></mt:SetVarBlock>
<mt:SetVar name="count" value="0">
<ul><li class="home"><a href="/blog/" title="トップページへ戻る">ホーム</a><ul><li>
<mt:ParentCategories glue="<ul><li>">
<mt:SetVar name="count" op="+" value="1">
<mt:SetVarBlock name="loopEntCat"><$mt:CategoryLabel$></mt:SetVarBlock>
<mt:If tag="CategoryCount">
<a<mt:If name="loopEntCat" eq="$thisEntCat"> class="current"</mt:If> href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a>
<mt:Else>
<$mt:CategoryLabel$>
</mt:If>
</mt:ParentCategories>

<mt:SubCategories include_current="0" category="$thisEntCat">
<mt:SubCatIsFirst><ul></mt:SubCatIsFirst>
<mt:If tag="CategoryCount">
<li><a href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a><$mt:SubCatsRecurse$></li>
<mt:Else>
<li><$mt:CategoryLabel$><$mt:SubCatsRecurse$></li>
</mt:If>
<mt:SubCatIsLast></ul></mt:SubCatIsLast>
</mt:SubCategories>

<mt:For var="i" from="0" to="$count"></li></ul></mt:For>
</mt:If>

説明も最後に息切れした感じもしますが、これで完成しました。

以上です。