タグクラウドとかいう言葉、最近はあまり聞かなくなりましたが、Movable Type で、あるカテゴリに属した記事に付けられたタグ (エントリータグ) だけを一覧として表示するためのテンプレートの記述方法について解説。
特に変わったことはしていないですけども、標準のエントリータグ関連の MT タグ (ややこしい) だけでは実現できないのとエントリータグ周りの件は使う人が少ないのか、情報もほとんどなかったのでメモ代わりに書いておきます。
通常のエントリータグ関連の MT タグだけの場合
ある Blog 内で使われているエントリータグの一覧を単純に出力するなら <mt:Tags> タグがありますし、特定のエントリーで使われているエントリータグの一覧を出力したければ、<mt:EntryTags> タグが用意されていますのでそれを使用しますが、これら MT タグに対して、<mt:Entries> タグの category / categories モディファイアのようなものが存在しないため、「特定のエントリーカテゴリで使われたエントリータグだけ」 を出力するということが簡単にはできません。面倒ですね。
配列を使って mt:Loop を回すのが定番の方法
じゃあどうしましょうかということで、一番最初に思いつくのはハッシュの配列にエントリータグを入れておいて、<mt:Loop> タグで出力する方法。で、実際にそれでうまくいきます。
カテゴリアーカイブで使用する場合
カテゴリアーカイブテンプレート上で、そのカテゴリ内で使われているエントリータグの一覧を出力したい場合は下記のような感じでテンプレートを記述します。
<mt:Entries lastn="0">
<mt:EntryTags>
<$mt:TagName setvar="tag_name"$>
<$mt:TagRank setvar="tag_rank"$>
<$mt:SetVar name="entry_tags" key="$tag_name" value="$tag_rank"$>
</mt:EntryTags>
</mt:Entries>
<ul>
<mt:Loop name="entry_tags" sort_by="value numeric">
<mt:If name="__counter__" le="21">
<li class="tag-rank-<$mt:GetVar name="__value__"$>">
<a href="<$mt:CGIPath$><$mt:SearchScript$>?tag=<$mt:GetVar name="__key__" encode_url="1"$>&blog_id=n"><$mt:GetVar name="__key__"$></a>
</li>
</mt:If>
</mt:Loop>
</ul>
<mt:Entries lastn="0"> 内で <mt:EntryTags> タグを使うことで、カテゴリ内の全記事で使われているエントリータグの一覧が出力されるのがわかります。それを <$mt:SetVar> タグを使用して配列に入れていきます。
なお上のサンプルでは、あとで並び替えやスタイルの調整とかをしやすくするため、<$mt:TagRank> タグを使用して、タグの使用頻度も取得しています。
ただし、この方法だと、記事 1件ごとに処理していくので、複数の記事に同じエントリータグが付いている場合は重複して出力されます。ですが、重複した値に関しては配列に格納される際に上書きされていくので、最終的には最後に出力されたものだけが残り、結果オーライになります。だから気にしなくて大丈夫。
ここまでくればあとは <mt:Loop> タグで配列から値を取得しつつ、必要な回数、一覧用のテンプレート部分を出力してあげれば完成です。前述したサンプルソースでいうところの下記の部分ですね。
<ul>
<mt:Loop name="entry_tags" sort_by="value numeric">
<mt:If name="__counter__" le="21">
<li class="tag-rank-<$mt:GetVar name="__value__"$>">
<a href="<$mt:CGIPath$><$mt:SearchScript$>?tag=<$mt:GetVar name="__key__" encode_url="1"$>&blog_id=n"><$mt:GetVar name="__key__"$></a>
</li>
</mt:If>
</mt:Loop>
</ul>
ここでは、各カテゴリで大量のエントリータグが使われていた時に大変なことにならないように、<mt:If name="counter" le="21"> としてループ回数を制限していますが、これは必要に応じて。
全部のエントリータグを出力したいなら、<mt:If> は不要です。
インデックステンプレートで使用する場合
インデックステンプレート上で、特定のカテゴリ内で使われているエントリータグの一覧を出力したい場合は下記のような感じでテンプレートを記述します。先ほどのテンプレートと基本は同じですが、<mt:Entries> タグに category モディファイアを指定しているだけです。
<mt:Entries category="カテゴリ名" lastn="0"> <mt:EntryTags> <$mt:TagName setvar="tag_name"$> <$mt:TagRank setvar="tag_rank"$> <$mt:SetVar name="entry_tags" key="$tag_name" value="$tag_rank"$> </mt:EntryTags> </mt:Entries> ・・・省略・・・
細かい調整は環境に応じて行ってみてください。
改行とか削除したいなら strip_linefeeds モディファイア
もし出力されるソースコード上の改行が邪魔であれば、下記のようにして改行を削除して出力しましょう。strip_linefeeds グローバル・モディファイアを使用すれば簡単。
・・・省略・・・
<ul>
<mt:Loop name="entry_tags" sort_by="value numeric">
<mt:If strip_linefeeds="1" name="__counter__" le="21">
<li class="tag-rank-<$mt:GetVar name="__value__"$>">
<a href="<$mt:CGIPath$><$mt:SearchScript$>?tag=<$mt:GetVar name="__key__" encode_url="1"$>&blog_id=n"><$mt:GetVar name="__key__"$></a>
</li>
</mt:If>
</mt:Loop>
</ul>
あるいは下記のような感じでも同じですね。
<mt:Unless strip_linefeeds="1"> <mt:Entries lastn="0"> <mt:EntryTags> <$mt:TagName setvar="tag_name"$> <$mt:TagRank setvar="tag_rank"$> <$mt:SetVar name="entry_tags" key="$tag_name" value="$tag_rank"$> </mt:EntryTags> </mt:Entries> ・・・省略・・・ </ul> </mt:Unless>
こっちの <mt:Unless strip_linefeeds="1"> で全体を囲んでしまう方法の方がソースコードはすっきりします。