処理中のサブカテゴリを起点にしてブログ記事のカテゴリを表示する

昨日のご質問の続きで、以下のようなご質問をいただきました。

SubCategories で MTParentCategories を使った場合、トップレベルカテゴリまでたどるのではなく、元のカテゴリまでのたどる方法はないでしょうか。

変数と条件判断を組み合わせれば、このようなことも可能です。
その方法を解説します。

1.例

例として、以下のように出力するものとします。

あるブログでは、カテゴリとブログ記事が、以下のような構造になっているとします。

  • カテゴリA
    • ブログ記事A-1
    • カテゴリB
      • ブログ記事B-1
      • カテゴリC
        • ブログ記事C-1

そして、「カテゴリA」のカテゴリアーカイブページを出力する際に、「カテゴリA」およびそのサブカテゴリに属する記事を、MTSubCategoriesタグを利用して、以下のような形で出力するものとします。

  • このカテゴリの記事一覧
    • ブログ記事A-1の情報
  • 「カテゴリB」の記事一覧
    • ブログ記事B-1の情報
  • 「カテゴリB」→「カテゴリC」の記事一覧
    • ブログ記事C-1の情報

また、「カテゴリB」のカテゴリアーカイブページでは、「カテゴリB」およびそのサブカテゴリに属する記事を、MTSubCategoriesタグを利用して、以下のような形で出力するものとします。

  • このカテゴリの記事一覧
    • ブログ記事B-1の情報
  • 「カテゴリC」の記事一覧
    • ブログ記事C-1の情報

2.考え方

MTParentCategoriesタグを使うと、あるカテゴリを、トップレベルのカテゴリから順に出力することができます。
ただ、「あるカテゴリを起点にして、そこから下の階層のカテゴリを出力する」という機能は、残念ながらありません。
この処理を変数と条件判断を使って作ります。

例えば、前述の話で、カテゴリAのカテゴリアーカイブページを再構築する中で、子カテゴリBの記事一覧を出力する前に、「カテゴリBの記事一覧」と表示することを考えてみます。
MTSubCategorieタグのブロックの中で、MTParentCategoriesタグを使えば、「カテゴリA」→「カテゴリB」のように、トップレベルのカテゴリから順に出力することができます。
その際に、「カテゴリAまで階層を下ったかどうか」を判断して、下っていればカテゴリ名を出力し、そうでなければ何も出力しない、というようにします。

3.タグの組み方

実際にMTSubCategoriesタグのブロックを作ると、以下のようになりました。

<mt:CategoryID setvar="cur_cat_id">
<mt:SubCategories include_current="1" sort_method="SortCatFld::Sort">
  <div>
  <mt:CategoryID setvar="sub_cat_id">
  <mt:If name="cur_cat_id" eq="$sub_cat_id">
    このカテゴリ
  <mt:Else>
    <mt:SetVar name="is_this_cat" value="0">
    <mt:ParentCategories>
      <mt:If name="is_this_cat">
        「<mt:CategoryLabel>」
        <mt:HasSubCategories>→</mt:HasSubCategories>
      </mt:If>
      <mt:CategoryID setvar="cat_id">
      <mt:If name="cat_id" eq="$cur_cat_id">
        <mt:SetVar name="is_this_cat" value="1">
      </mt:If>
    </mt:ParentCategories>
  </mt:If>
  の記事
  </div>
  ブログ記事の一覧を出力する部分
  <mt:SubCatsRecurse>
<mt:SubCategories>

3-1.1行目

再構築中のカテゴリのIDを、変数cur_cat_idに代入します。

3-2.2行目

再構築中のカテゴリと、そのサブカテゴリを、MTSubCategoriesタグを使って順に出力します。

3-3.4~7行目

MTSubCategoriesタグで処理しているカテゴリのIDを、変数sub_cat_idに代入します。
そして、変数sub_cat_idと変数cur_cat_idの値が等しい場合(処理中のカテゴリが、再構築中のカテゴリである場合)は、「このカテゴリ」と出力します。
一方、両者の値が等しくない場合(処理中のカテゴリが、サブカテゴリである場合)は、7行目のMTElseタグ以降の処理を行います。

3-4.8行目

このあとで、MTParentCategoriesタグを使って、トップレベルカテゴリから、現在処理中のカテゴリまで、階層を順に下ります。
その際に、再構築中のカテゴリまで階層を下ったら、その後は下の階層のカテゴリ名を出力します。

「再構築中のカテゴリまで階層を下った」ということは、変数is_this_catに保存することにします。
MTParentCategoriesタグの処理に入る前では、まだカテゴリを下っていないので、この変数に0を代入しておきます。
後の処理で、再構築中のカテゴリまで階層を下ったら、この変数に1を代入します。

3-5.10~13行目

変数is_this_catの値が1(つまり、再構築中のカテゴリまで階層を下った後)の場合は、カテゴリ名を出力します。
また、カテゴリの各階層の間には「→」を出力しますが、一番下の階層のカテゴリの場合は、その後には「→」は出力しません。
そこで、下の階層がある(MTHasSubCategory)ときだけ、「→」を出力します。

3-6.14~17行目

MTParentCategoriesタグで処理しているカテゴリ(変数cat_id)と、再構築中のカテゴリ(変数cur_cat_id)とを比較して、両者が一致したら、変数is_this_catの値を1にします。