MTSetVar(Block)/MTIfタグの具体的な利用例。
公開日 : 2007-10-15 13:24:10
まずはお詫び。
先週土曜日の分科会、「テーブルリーダー」ということだったのですが、僕のテーブル以外は「セミナー」なのか「テーマ設定して取り組み」なのかはっきりやられていたみたいです。僕のところは「ゆるい」設定で各自のテーマ! ってことでやってしまったので限られた時間の中で成果を実感できなかったかもしれません。ごめんなさい(ということで、ちゃんとしたレポートになってませんが重ねてごめんなさい!)。
うまくいかなかったらちゃんとフォローアップすればいいんだと考えるのだ!
という反省もあって、当日出ていた話題に対する実装方法の例をここで挙げてみたい。当日うまく出来なくて何か消化不良だった人は参考にしてください。
MTSetVarとMTIfを駆使しよう
荒木さんも藤本さんも、MT4のテンプレート使いこなしのキモ? は MTSetVar (mt:setvar) と MTIf (mt:if) って言ってらっしゃった(と解釈しています) し、黒野さんが挙げていたテーマもそのあたりを活用した分岐のさせ方だったので、実際に話に出ていた「同じタグを含む他のエントリーのリストをエントリーアーカイブに表示させる」という例で少し解説してみたいと思います(一応実際に書いて動作させてみてますけど間違いあったらツッコミ歓迎)。
「関連するエントリー」を簡単に実現する例 (同一のタグ付きエントリー一覧をエントリーアーカイブに表示する)
関連するエントリーを判断するのに何をもって行うかという話はあるとして、今回は「同一のタグが付いているものを関連するエントリーとして」扱いたい、ということでした。 プラグインを使えば出来るよってな話はあがっていたのですが(小川さんのTagSupplementalsプラグイン)、今回はMTタグだけで実現してみたいということだったので以下のように考えてやってみました。
最初のテンプレート
<MTEntryIfTagged>
<MTSetVarBlock name="entrytags"> <!--(*注)-->
<MTEntryTags glue=" OR "> <!--←関連性をより強くするなら AND-->
<$MTTagName$>
</MTEntryTags>
</MTSetVarBlock>
<!--$entrytags は例えば「Movable Type OR アクセシビリティ」のようになる -->
<MTEntries tag="$entrytags" lastn="10">
<!--<MTEntries tag="Movable Type OR アクセシビリティ" lastn="10">と同義-->
<MTEntriesHeader>
<ul>
</MTEntriesHeader>
<li><a href="<MTEntryPermalink>"><MTEntryTitle></a></li>
<MTEntriesFooter>
</ul>
</MTEntries>
</MTEntryIfTagged>
(*注: スタティック生成の時には MTSetVarBlockの中に改行を入れると複数タグが含まれるエントリーでエラーになります。MTSetVarBlock内に改行を入れずに記述すれば通ります)
このテンプレートによってエントリーに付けたタグと同じタグの付いたエントリーのリスト(Max)10件が出力されます。手順としては、
- MTSetVarBlock で MTEntries のモディファイア (アトリビュート) を組み立てて
- <MTEntries tag="$entrytags" lastn="10"> のように変数 $entrytags をモディファイア (アトリビュート)に指定する
という流れです。
さて、これで同じタグの付いたエントリーを表示できることはできましたが、このやり方だと当該エントリー (そのエントリー自身) が関連項目としてリストアップされて不細工です。そこで以下のように修正します。
改良版テンプレート
<MTEntryIfTagged>
<MTSetVarBlock name="entrytags">
<MTEntryTags glue=" OR ">
<$MTTagName$>
</MTEntryTags>
</MTSetVarBlock>
<MTSetVarBlock name="thisid"><MTEntryID></MTSetVarBlock>
<!--↑当該エントリーのIDを 変数 $thisid にセット-->
<MTEntries tag="$entrytags" lastn="10">
<MTSetVarBlock name="eid"><MTEntryID></MTSetVarBlock>
<!--↑ループ内で呼ばれたエントリーのID を $eidにセット-->
<MTEntriesHeader>
<ul>
</MTEntriesHeader>
<MTUnless name="eid" eq="$thisid"> <!--$thisid と $eid が同じでなければ-->
<li><a href="<MTEntryPermalink>"><MTEntryTitle></a></li>
</MTUnless>
<MTEntriesFooter>
</ul>
</MTEntriesFooter>
</MTEntries>
</MTEntryIfTagged>
これで当該エントリーは除外されるようになりました。
さてさて、まだ改善の余地がありそうですね。
- 当該エントリー以外に同一のタグが付いたエントリーがなかった時(つまり、ブログ内ではじめて付けたタグの場合)、中身がないのに<ul>,</ul>を出力してしまう。
- Max10件を表示させたいのに 場合によっては 9件しか表示されない場合が出てくる。
これらの点をクリアするようにテンプレートを修正してみます。
最終版テンプレート
もうこのくらいになると答えは一つではないけれど、これで意図した結果が得られます。ちなみに、関連するエントリーの並び順を明示したい場合は sort_by, sort_orderを指定することになります。
<MTEntryIfTagged>
<MTSetVarBlock name="entrytags">
<MTEntryTags glue=" OR ">
<$MTTagName$>
</MTEntryTags>
</MTSetVarBlock>
<MTSetVarBlock name="thisid"><MTEntryID></MTSetVarBlock>
<MTSetVar name="match" value="0"> <!--←当該エントリーがマッチしたかどうか-->
<MTEntries tag="$entrytags" lastn="11"> <!--←10件でなく11件にしておく-->
<MTSetVarBlock name="eid"><MTEntryID></MTSetVarBlock>
<MTSetVarBlock name="entryCount"><MTEntriesCount></MTSetVarBlock> <!--←何件マッチしたか-->
<MTIf name="entryCount" gt="1">
<!--↑1件以上マッチしたら出力 / 1件だったら当該エントリのみと判断できる-->
<MTEntriesHeader>
<ul>
</MTEntriesHeader>
<MTUnless name="__last__"> <!--←ループの最後でなければ-->
<MTUnless name="eid" eq="$thisid">
<li><a href="<MTEntryPermalink>"><MTEntryTitle></a></li>
<MTElse>
<MTSetVar name="match" value="1"> <!--←当該エントリーがマッチしたことを覚えておく!-->
</MTElse>
</MTUnless>
<MTElse> <!--←ループの最後ならば-->
<MTIf name="match"> <!--←当該エントリと既に一致していた場合は11件目を表示-->
<li><a href="<MTEntryPermalink>"><MTEntryTitle></a></li>
<MTElse>
<MTIf name="__counter__" ne="11"> <!--←11件に満たない場合も無条件に表示-->
<li><a href="<MTEntryPermalink>"><MTEntryTitle></a></li>
</MTIf>
</MTElse>
</MTIf>
</MTElse>
</MTUnless>
<MTEntriesFooter>
</ul>
</MTEntriesFooter>
</MTIf>
</MTEntries>
</MTEntryIfTagged>
最後の</ul>は__last__のブロックに突っ込んでも一向に構わないだろうけど、テンプレートの可読性を考えてこのように。 結構複雑になるけれども、プラグインが無くてもテンプレートタグ(特に MTSetVar と MTIf を活用すれば) このくらいの分岐は可能です。
ループの途中でマッチした際に $match に「1」をセットするあたり、もはや「タグ」でもなくてプログラミング的な思考が問われるところですが、MT扱うマークアップエンジニアの人はMTSetVar と MTIf を駆使できるようになると幅が広がると思うよ!