「WordPressで学ぶPHP(1)変数・制御構造編」が発売されました。
「WordPressで学ぶPHP」シリーズの第1巻で、WordPressを通してPHPを学んでいく本です。
この本では、PHPの基本となる変数と制御構造について解説します。
Kindle本で、定価500円です。
孫カテゴリアーカイブに子のリスト表示をする
MTQに「孫カテゴリアーカイブに子のリスト表示をする」という質問が上がっていました。
この質問に答えてみます。
1.考え方
まず、ご希望のようなことを行う際の考え方をまとめます。
1-1.カテゴリの階層を得る
親/子/孫の3階層のカテゴリがあって、孫カテゴリのアーカイブページでだけ、特別な出力をしたいということです。
そのためには、現在出力中のカテゴリアーカイブページが、どの階層のカテゴリのアーカイブページかを調べる必要があります。
そこで、カテゴリの階層を調べる処理を行います。
MTParentCategoriesタグで、親からそのカテゴリまでを得ます。
そして、その間のカテゴリの数を数えて、階層の深さを調べます。
1-2.孫カテゴリとその上の子カテゴリにマークを付ける
孫カテゴリと、その上の子カテゴリには、カレントを示すマークをつけたいということです。
そこで、現在出力中の孫カテゴリと、その上の子カテゴリに、カレントであることを表す値をセットします。
この処理はハッシュを使って行います。
「parent_cat_ids」という名前のハッシュを作り、キーをカテゴリIDにし、そのキーに対応する値を1にします。
例えば、ある孫カテゴリのIDが15で、その上の子カテゴリのIDが10だとします。
この場合、parent_cat_ids{15}と、parent_cat_ids{10}の値を1にします。
1-3.親カテゴリの時だけ処理をする
孫カテゴリから見て、同一の親を持つカテゴリをツリーで出力したいということです。
あるカテゴリから見て、その最上位の親のカテゴリを直接的に得る方法は、残念ながらありません。
ただ、MTParentCategoriesタグを使って、繰り返しの最初の時だけ処理を行えば、間接的に最上位の親のカテゴリを得ることができます。
この処理は、以下のようにタグを組んで行うことができます。
<$mt:SetVar name="is_parent" value="1"$> <mt:ParentCategories> <mt:If name="is_parent" eq="1"> 最上位の親カテゴリの時の処理 <$mt:SetVar name="is_parent" value="0"$> </mt:If> </mt:ParentCategories>
「最上位である」ということを判断するために、1行目のMTSetVarタグで、変数is_parentに1を代入します。
次に、2行目と7行目のMTParentCategoriesタグで、最上位のカテゴリから順に繰り返します。
繰り返しの1回目(=最上位)では、変数is_parentの値が1になっています。
したげって、3行目のMTIfタグの条件が成立して、4行目以降に進み、最上位の親カテゴリの時の処理を行います。
そして、5行目のMTSetVarタグで、変数is_parentに0を代入して、「最上位である」という状況をオフにします。
一方、繰り返しの2回目以降では、1回目の最後で変数is_parentに0を代入したので、3行目のMTIfタグの条件は成立しません。
したがって、4行目と5行目の処理は行われず、結果として何も起こらないことになります。
2.テンプレートの組み方の例
ここまでの話に沿って、実際にテンプレートを組むと、以下のようになります。
<$mt:SetVar name="cur_depth" value="0"$> <mt:ParentCategories> <$mt:CategoryID setvar="cat_id"$> <$mt:SetVar name="parent_cat_ids" key="$cat_id" value="1"$> <$mt:SetVar name="cur_depth" op="++"$> </mt:ParentCategories> <mt:If name="cur_depth" eq="3"> <$mt:SetVar name="is_parent" value="1"$> <mt:ParentCategories> <mt:If name="is_parent" eq="1"> <mt:SubCategories> <mt:SubCatIsFirst><ul></mt:SubCatIsFirst> <$mt:CategoryID setvar="cat_id"$> <mt:If name="parent_cat_ids" key="$cat_id"> <mt:If tag="CategoryCount"> <li><a href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$>★</a> <mt:Else> <li><$mt:CategoryLabel$>★ </mt:If> <$mt:SubCatsRecurse$> <mt:Else> <mt:If tag="CategoryCount"> <li><a href="<$mt:CategoryArchiveLink$>"><$mt:CategoryLabel$></a> <mt:Else> <li><$mt:CategoryLabel$> </mt:If> </mt:If> <mt:SubCatIsLast></ul></mt:SubCatIsLast> </mt:SubCategories> <$mt:SetVar name="is_parent" value="0"$> </mt:If> </mt:ParentCategories> </mt:If>
6行目までの部分は、上記の1-1.と1-2.に沿った部分です。
カテゴリの階層の深さを、変数cur_depthに求めます。
また、ハッシュparent_cat_idsを使って、孫カテゴリからその親までの各カテゴリに、カレントであることを表す値をセットしています。
8/34行目では、MTIfタグを使って、変数cur_depthの値が3(=孫カテゴリ)の時だけ、処理を行うようにしています。
9/10/11/32/33行目は、上記の1-3.に沿った処理です。
そして、11~31行目で、MTSubCategoriesタグを使って、カテゴリのリストを出力しています。
まず、各カテゴリを出力する際に、カレントかどうかで、出力を分けます。
この処理は、14行目のMTSetVarタグと、15/22/28行目のMTIfタグで行っています。
14行目で、変数cat_idにカテゴリのIDを代入します。
15行目のMTIfタグで、ハッシュ内のそのIDのカテゴリの値を調べ、カレントを表す値(1)が入っているかどうかを判断して、処理を分けます。
16~21行目は、カレントである場合の処理です。
カテゴリのラベルの後に、カレントのマーク(★)を出力しています。
また、カレントのカテゴリの場合は、その下の階層も出力するので、MTSubCatsRecurseタグを使っています(21行目)。
一方、23~27行目は、カレントでない場合の処理です。
こちらの場合は、下の階層は出力しないので、MTSubCatsRecurseタグを入れていません。