Movable Type でカテゴリごとの投稿者名とその投稿者の記事数を表示するカスタマイズ

Movable Type で、すべてのページで同じように、トップレベルカテゴリからのカテゴリごとの投稿者名とその投稿者の記事数を表示するカスタマイズを行ってみました。

僕のブログでは、ユーザーが僕一人( tinybeans )なので使用用途がありませんが、テストで一人ユーザーを追加して( tinybeans_org )、記事を1本投稿してみました。表示結果は次のようになります。

categories_author01.gif

例えば、上図では、トップレベルカテゴリ「 Book 」には、tinybeans が記事を 11本、tinybeans_org が記事を 1本投稿しています。その次のトップレベルカテゴリ「 Diary 」には、tinybeans しか記事を投稿していません。

完成したソース

完成したソースは次のようになります。このソースをサイドバーのウィジェットなどにペーストすれば使えると思います。

<mt:TopLevelCategories>
<mt:SubCatIsFirst>
<ul>
</mt:SubCatIsFirst>
 <mt:If tag="CategoryCount">
 <li><a href="<$mt:CategoryArchiveLink$>"<mt:If tag="CategoryDescription"> title="<$mt:CategoryDescription$>"</mt:If>><$mt:CategoryLabel$> (<$mt:CategoryCount$>)</a>
 <mt:Else>
 <li><$mt:CategoryLabel$>
 </mt:If>
 <ul>
 <mt:Authors need_entry="0">
 <$mt:AuthorName setvar="author_name"$>
 <$mt:SetVar name="entry_count" value="0"$>
 <li><$mt:AuthorName$> (<mt:Entries author="$author_name"><mt:EntriesHeader><$mt:EntriesCount$><$mt:SetVar name="entry_count" value="1"$></mt:EntriesHeader></mt:Entries><mt:Unless name="entry_count">0</mt:Unless>)
 </mt:Authors>
 </ul>
 <$mt:SubCatsRecurse$>
 </li>
<mt:SubCatIsLast>
</ul>
</mt:SubCatIsLast>
</mt:TopLevelCategories>

目標とする表示結果

このカスタマイズの目標とする表示結果は次のようになります。

  • トップレベルカテゴリ名 A ( A 内のブログ記事数)
  • 著者名 X ( X が A 内に書いたブログ記事数)
  • 著者名 Y ( Y が A 内に書いたブログ記事数)
    • サブカテゴリ名 a ( a 内のブログ記事数)
    • 著者名 X ( X が a 内に書いたブログ記事数)
    • 著者名 Y ( Y が a 内に書いたブログ記事数)

この状態で、全ページに共通して表示させます。

解説

MTTopLevelCategories タグでトップレベルカテゴリから表示

全体を MTTopLevelCategories タグで囲むことにより、トップレベルカテゴリから階層構造を維持した状態でカテゴリをループします。

MTSubCatIsFirst と MTSubCatIsLast は、それぞれの階層の最初と最後に 1回ずつ中身を処理するテンプレートタグです。

<mt:TopLevelCategories>
<mt:SubCatIsFirst>
<ul>
</mt:SubCatIsFirst>
...
<mt:SubCatIsLast>
</ul>
</mt:SubCatIsLast>
</mt:TopLevelCategories>

MTAuthors で投稿者に関する情報を出力

まず先に、下段の投稿者部分を解説します。

 <ul>
 <mt:Authors need_entry="0">
 <$mt:AuthorName setvar="author_name"$>
 <$mt:SetVar name="entry_count" value="0"$>
 <li><$mt:AuthorName$> (<mt:Entries author="$author_name"><mt:EntriesHeader><$mt:EntriesCount$><$mt:SetVar name="entry_count" value="1"$></mt:EntriesHeader></mt:Entries><mt:Unless name="entry_count">0</mt:Unless>)
 </mt:Authors>
 </ul>

全体を ul 要素と MTAuthors タグで囲み、投稿者に関する情報を出力させます。MTAuthors タグに「 need_entry="0" 」を付けることで、現在ループ中のカテゴリにブログ記事を投稿していない投稿者についても出力させています。

3行目の MTAuthorName タグに setvar モディファイアを付けて、ループ中の投稿者名を変数 author_name に代入します。

4行目の MTSetVar タグで変数 entry_count を定義します。

5行目は重要なので以下で詳しく解説します。

MTEntries タグの author モディファイアで指定した投稿者の書いたブログ記事を出力

ここでは見やすくするために改行します。

<li><$mt:AuthorName$> (
<mt:Entries author="$author_name">
 <mt:EntriesHeader>
 <$mt:EntriesCount$>
 <$mt:SetVar name="entry_count" value="1"$>
 </mt:EntriesHeader>
</mt:Entries>
<mt:Unless name="entry_count">0</mt:Unless>
)

まず MTAuthorName タグでループ中の投稿者名を表示させ、その次のカッコ内に、その投稿者が現在ループ中のカテゴリに書いたブログ記事数を表示させます。

カッコ内は、まず、<mt:Entries author="$author_name"> とすることで、先ほどセットしたループ中の投稿者が書いたブログ記事のみ扱うようにします。

その次に MTEntriesHeader タグを付け、MTEntries タグのループの最初の一回のみ中身を出力するようにします。

MTEntriesCount タグで、現在 MTEntries タグで扱うブログ記事数を表示します。

その次の MTSetVar タグで、先ほど定義した変数 entry_count に 1 を代入します。

その次の MTUnless タグで、変数 entry_count の値が 0 以外でない場合(つまり 0 の場合)のみ 0 を表示させるようにします。この部分がちょっと難しかったところです。最初は、MTEntries タグの中で、<mt:If tag="EntriesCount"> などで条件分岐しようと思ったのですが、ブログ記事の投稿がない投稿者の場合、MTEntries タグの中身自体が処理されなくなってしまうのでダメでした。

投稿者部分は以上です。

<mt:If tag="CategoryCount"> でブログ記事があるカテゴリのみカテゴリーアーカイブへリンクさせる

 <mt:If tag="CategoryCount">
 <li><a href="<$mt:CategoryArchiveLink$>"<mt:If tag="CategoryDescription"> title="<$mt:CategoryDescription$>"</mt:If>><$mt:CategoryLabel$> (<$mt:CategoryCount$>)</a>
 <mt:Else>
 <li><$mt:CategoryLabel$> (0)
 </mt:If>
 【先ほどの投稿者部分が入る】
 <$mt:SubCatsRecurse$>
 </li>

カテゴリ部分は単純で、ポイントは次の二つです。

  • <mt:If tag="CategoryCount"> でブログ記事があるカテゴリのみカテゴリーアーカイブへリンクさせる。
  • カテゴリをリストアップする li 要素は閉じず、条件分岐と著者部分が終わった後に、MTSubCatsRecurse タグを入れてから li 要素を閉じる。

これで完成です。投稿者部分だけを切り離したり、ブログ記事の投稿の無いカテゴリ、投稿者の扱いを変更したりすれば、出力結果はいろいろと応用できます。

以上です。