MTTopLevelCategoriesタグで記事がないカテゴリを出力しない(その1)

先日、「MTTopLevelCategoriesタグでカテゴリ一覧を出力する際に、記事がないカテゴリを出力しない方法を知りたい」という質問を受けました。
結構奥が深い話なので、記事にしてみます。

1.MTCategoryCountタグで記事数を調べる

カテゴリの情報を出力できる状況では、「MTCategoryCount」というテンプレートタグで、そのカテゴリに属する記事の数を調べることができます。
「記事がないカテゴリは出力しない」ということは、「そのカテゴリの記事の数が0でない何かを出力する」ということに等しいです。

そこで、MTCategoryCountタグの値が0でないかどうかで、記事がないカテゴリを判断することができます。
基本的なテンプレートの書き方は、以下のようになります。
3行目のMTIfタグで、MTCategoryCountタグの値が0でないことを判断しています。

<mt:TopLevelCategories>
  ...
  <mt:If tag="CategoryCount">
    記事があるカテゴリの時に出力する内容
  </mt:If>
  ...
</mt:TopLevelCategories>

2.サブカテゴリがあれば出力する

記事がないカテゴリでも、子カテゴリがあれば、出力したい場合もあります。

2-1.出力が必要になる状況

MTTopLevelCategoriesタグは、ul/li要素でカテゴリのツリーを出力する際に使うことが多いです。
この場合、記事がないカテゴリであっても、子カテゴリがあるカテゴリは、出力する必要があります。

例えば、カテゴリの構造が以下のようになっているとします(カッコ内の数字は、そのカテゴリの記事の数)。
この場合、親1カテゴリには記事はありませんが、親1カテゴリも出力しないと、ツリーを正しく表現することができません。

├ 親1(0)
│ ├ 子1-1(10)
│ └ 子1-2(15)
├ 親2(5)
...

そこで、「記事があるか、または子カテゴリがあれば、そのカテゴリを出力する」という条件判断に変えます。
子カテゴリがあるかどうかは、MTHasSubCategoriesタグで調べることができます。

2-2.2つの条件のOR

今取り上げている例では、「記事がある」「子カテゴリがある」の2つの条件のどちらかが成立したかどうかで、処理を分けます。
ただ、MTIfタグにはORに相当する機能がありません。
そこで、以下のような手法を取ります。

  • フラグ用の変数の作り、値を0にします。
  • 1つ目の条件判断を行い、条件が成立していれば、フラグ用フラグ用の変数の値を1にします。
  • 2つ目の条件判断を行い、条件が成立していれば、フラグ用フラグ用の変数の値を1にします。

すると、2つの条件のどちらかが成立すれば、フラグ用変数の値が1になります。
一方、どちらの条件も成立していなければ、フラグ用変数の値は0のままです。
後は、以下のようなタグで、2つの条件のどちらかが成立した時の出力を行います。

<mt:If name="フラグ用変数">
  2つの条件のどちらかが成立した時に出力する内容
</mt:If>

2-3.テンプレートの例

ここまでの話に基づいて、ul/li要素でカテゴリ構造のツリーを出力する際に、記事がないカテゴリでも子カテゴリがあれば出力するには、以下のようにテンプレートを組みます。

<mt:TopLevelCategories>
  <mt:SubCatIsFirst><ul></mt:SubCatIsFirst>
  <$mt:SetVar name="flag" value="0"$>
  <mt:If tag="CategoryCount">
    <$mt:SetVar name="flag" value="1"$>
  <mt:Else>
    <mt:HasSubCategories>
      <$mt:SetVar name="flag" value="1"$>
    </mt:HasSubCategories>
  </mt:If>
  <mt:If name="flag">
    <li><$mt:CategoryLabel$>(<$mt:CategoryCount$>)
    <$mt:SubCatsRecurse$>
    </li>
  </mt:If>
  <mt:SubCatIsLast></ul></mt:SubCatIsLast>
</mt:TopLevelCategories>

3~10行目が、「記事があるか、または子カテゴリがある」という条件判断を行う部分です。

3行目で、まず変数flagの値を0にします。
4行目のMTIfタグで、カテゴリの記事の数が0でないことを判断し、その条件を満たしていれば、5行目で変数flagの値を1にします。

カテゴリの記事の数が0の時はMTElseタグのブロックに進みます。
7~9行目によって、サブカテゴリがあれば、変数flagの値が1になります。
結果として、記事があるか、または子カテゴリがあれば、変数flagの値が1になります。

その後、11行目のMTIfタグで、変数flagの値が1なら、そのカテゴリの名前と記事数を出力します(12行目)。

3.まだ問題がある

上記のテンプレートで、おそらく大半の場合は正しい出力を得ることができます。
しかし、状況によっては、意図しない出力になることがあります。
それについては明日の記事で解説します。

MT Cloud Starter Kit
Movable Typeのプラグイン集「MT Cloud Starter Kit」をぜひご利用ください