Movable TypeもMovable Type 3からの長いつきあいなのに、まだハマることがあるので、書いてみたネタです。
●やりたいこと
今回は『カテゴリー別の最新記事●●件を表示するが、表示するものがなかった場合に▲▲を表示する』というテンプレートコードを書いてみます。
トップページやお知らせのページなどで、「新製品のお知らせ」「営業日のお知らせ」「キャンペーンについて」などのカテゴリー別の最新記事一覧を表示することがありますが、そういったものを作成します。
以下の画像の様なものですね。以下の画像の例では、「営業日のお知らせ」のカテゴリーで、現在公開されている記事がないので、「現在、お知らせする内容はございません」と表示しています。(ゴールデンウィークやお盆の時期、年末年始などに記事をアップするので、それ以外の時期は公開されている記事がない)
画像出典:お知らせ(吉田印刷所)
●ダメな例:mt:EntriesCount
まず、ダメな例。実際にやってしまってすごく悩みました(苦笑)。
「カテゴリー別の記事の数を数えて0件だったら▲▲を表示すればいい」
↓ ↓ ↓ ↓ ↓
「記事件数を表示する(出力する)タグはないかな?」
↓ ↓ ↓ ↓ ↓
特定のコンテキストの中で、出力される記事の件数を表示します。例えば、elephant というタグのついた記事のリストを出力する際に、その対象となる記事の件数を出力するのに使います。
MTEntriesCount | テンプレートタグリファレンス(Movable Type)
「おっ、ちょうどよく『mt:EntriesCount』があるじゃないか! さっそく組んでみよう~」
↓ ↓ ↓ ↓ ↓
それでできたコードがこちらです。
<mt:Entries category="営業日について" lastn="5"> <mt:If tag="mt:EntriesCount" ne="0"> 《記事があった場合の記述》 <mt:Else> 《記事がなかった場合の記述》 </mt:If> </mt:Entries>
- カテゴリーを指定して、最新の5件を1件ずつ出力(ループ開始)
- mt:EntriesCount タグの出力結果が「0」ではなかったら
- 《記事があった場合の出力》
- 違う場合は(=記事の件数ががない場合)
- 《記事がなかった場合の出力》
- 条件分岐はここまで
- ループはここまで
一見、ロジックは間違っていない気がしますが、大きな認識の誤りがあります。
「<mt:entries>~</mt:entries>」のループですが、そもそも該当する記事がない(=記事数が0件)と、ループの中の処理がされません。
極端な話、記事をまだ1件も投稿していない(公開していない)状態で、以下のテンプレートコードを実行しても何も表示されません。
<mt:Entries lastn="5"> いろはにほへと </mt:Entries>
これは理解できますよね。
先程のテンプレートコードもカテゴリーの絞り込みをしているだけで結局同じなのです。つまり「<mt:entries>~</mt:entries>」の中は出力されない、というより、通らないということです。
カテゴリーで絞り込んで「<mt:entries>~</mt:entries>」のループを通ってないので、ループ内にある『mt:EntriesCount タグの出力結果が「0ではなかったら」』という条件分岐も通らないので、記事数が0件かどうかという判定は先程のテンプレートコードではムリだということになります。
●正解:変数を使って判定
では意図した通りのテンプレートコードは何でしょう。
正しい方法は「ループの中を通ったかを変数を使って判定する」です。
テンプレートコードは以下の通りです。
<$mt:Var name="entries_flag" value="0"$> <mt:Entries category="営業日について" lastn="5"> 《記事があった場合の記述》 <$mt:Var name="entries_flag" value="1"$> </mt:Entries> <mt:Unless name="entries_flag"> 《記事がなかった場合の記述》 </mt:Unless>
- 変数「entries_flag」を初期化(0にする)
- カテゴリーを指定して、最新の5件を1件ずつ出力(ループ開始)
- 《記事があった場合の出力》
- 変数「entries_flag」に「1」をセット
- ループはここまで
- 変数「entries_flag」が「0」ではなかったら
- 《記事がなかった場合の出力》
- 条件分岐はここまで
ループの外側で判定するのがポイントです。
そんなに複雑ではないですね。(ちょっとループが回る度に毎回変数をセットするのが気になりますが…mt:EntriesFooterなどを使ってループの最後に変数をセットするというロジックを作るまでもないですし)
それでは、よいMovable Typeライフを。