[Gush2]複数のパンくずリストをキレイに表示する方法
Gush2のパンくずリストは、カテゴリの親子関係が一つの時しか正常に表示されない。
しかも、親子関係が一つでも、深くネスト(ひ孫カテゴリとか)してあると正常に表示されない場合がある。
これはGush2のパンくずリスト生成アルゴリズムに起因している。
wordpressでは、get_the_category()で投稿記事に登録されているカテゴリを配列で受け取る事ができる。
で、Gush2のアルゴリズムでは、その配列の一つ目の要素だけ参照し、そこからパンくずリストを作っている。
多分カテゴリを一つだけ登録することを想定して作ってあるんだと思う。
だから、カテゴリを複数登録した場合、その参照する要素が何になるのか分からない為、正常に表示できなくなってしまう。
例えば、「親カテゴリA > 子カテゴリB」という風にカテゴリ登録していた場合、参照したカテゴリが運よく「子カテゴリB」であれば正常にパンくずリストが表示されるが、参照したカテゴリが「親カテゴリA」であればパンくずリストに「子カテゴリB」は表示されない。
僕としては、複数の親子関係でかつネストが深くても正常にパンくずリストを生成してほしいので、以下のようなコードを作った。
これを、Gush2内の「single.php」の<div class='pankuzu>~<!--//pankuzu-->と置き換えれば動作するはず。
何ならこれを関数にして「function.php」に登録しておき、それを「single.php」から呼び出すという手もある。
ちなみに僕はそうしている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | <?php $postcat = get_the_category(); $catidlist_all = array(); $child_list = array(0); //出力するパンくずリストの一番下の子カテゴリを取得 while(count($postcat) != 0){ foreach ($child_list as $num_child =>$child) { $replaced = False; foreach ($postcat as $num => $cat) { if($cat->category_parent == $child->cat_ID){ $child_list[] = $cat; $replaced = True; unset($postcat[$num]); } } if($replaced == True){ unset($child_list[$num_child]); } } } //$child_listから、出力する「パンくずリスト」リストを生成 foreach ($child_list as $key => $child) { $catid = $child->cat_ID; $allcats = array($catid); while(!$catid==0) { $mycat = get_category($catid); $catid = $mycat->parent; array_push($allcats, $catid); } array_pop($allcats); $catidlist_all[] = array_reverse($allcats); } // ----------------------------------------- // パンくずリストの出力開始 echo <<<EOF <div class="pankuzu"> <div id="breadcrumb"> EOF; // ----------------------------------------- foreach($catidlist_all as $catidlist){ $home_url = home_url(); // ----------------------------------------- // ホームの出力 echo <<<EOF <div itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> <a href="$home_url" itemprop="url"> <span itemprop="title">ホーム</span> </a> > </div> EOF; // ----------------------------------------- foreach($catidlist as $catid){ $cat_link = get_category_link($catid); $cat_name = get_cat_name($catid); // ----------------------------------------- // 各カテゴリの出力 echo <<<EOF <div itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> <a href="$cat_link" itemprop="url"> <span itemprop="title">$cat_name</span> </a> > </div> EOF; // ----------------------------------------- } echo '<br>'; } // ----------------------------------------- // パンくずリストの出力終了 echo <<<EOF </div> </div><!-- //pankuzu --> EOF; // ----------------------------------------- ?> |
すると、以下の画像のように正常に表示される。
簡単に説明すると、
- 一番下の子カテゴリだけを集めた配列を生成
- そこから「親子関係を持つパンくずリスト」リストを生成
- そのリストを元にパンくずリストを出力する
というアルゴリズムである。
例として、「A > B1, A > B2, あ > い」というカテゴリを設定した場合、
- get_the_category()で得た配列から[B1, B2, い]という配列を生成
- それぞれのカテゴリについて、親カテゴリを辿って
[[A, B1], [A, B2], [あ, い]]というリストを作る - 出力
という感じにデータを操作している。
1.の操作が終わったらget_category_parents()を使用して出力するのでも良かったが、Gush2ではリッチスニペットのための構造化データみたいなの(よく分かってない)も出力しているみたいなので、今回はそっちも出力できるようにした。
foreachをネストしてるので、登録カテゴリ数が超多くなると動作が遅くなるかもしれないが、登録カテゴリなんか多くても5,6個だろうし、動作の重さにはそんな影響しないと思う。
追記(2017/10/26)
1つバグというか気を付けないといけない点が分かったので書いておく。
このアルゴリズムだとホームから順に子カテゴリを辿っていくことになるので、ホームからみて孫カテゴリ以降のみを登録した場合(ホーム直下のカテゴリを登録し忘れた場合)、無限ループに入ってページが表示できなくなる。
まぁ子カテゴリである以上、親カテゴリは必ず登録すると思うので大丈夫だと思うけど、万が一チェック入れ忘れると500番のエラーが発生するので注意。
追記(2017/10/26)
ネストの深さが違うと、一番深さの深いカテゴリリストしか出てこないバグがあったので修正。
例)「A > B1, A > B2, あ」とカテゴリを設定した場合、「A > B1, A > B2」しか表示されない。
この記事へのコメントはこちら