PR

Cocoonでカテゴリー別にサイトマップを表示するプログラム

ワードプレスのテーマCocoonについて
この記事は約11分で読めます。

無料のワードプレス(以下WP)のテーマCocoonで作成者の「わいひら」様が下記のページでショートコードを公開されています。

ただお示ししていただいているコードでは、カテゴリーはカテゴリーだけの一覧で、投稿は投稿の一覧という形での表示になっています。

スポンサーリンク

なぜプログラムを修正する必要があるのか?

本サイトではカテゴリーの考え方には少々思い入れがあります。
下記の記事をご参照いただければ幸いです。

そのためサイトマップとしてはカテゴリーを持たない固定ページと、カテゴリー階層を反映した投稿の一覧を表示したいと考えました。

※なお本サイトでは、メニューとカテゴリーは同じ階層構造にするため、カテゴリーとしては親-子-子の3階層までとなります。従いまして4階層以上は考慮しておりません。

修正するにあたり

「わいひら」様も参考にされた下記のページも活用させていただきつつ、子テーマのfunction.phpにコーデングを追試しました。

なお変更したのはカテゴリー別の部分だけですが、パラメータとして「posts_per_page」( 1ページに含める投稿数)の値を渡せるようにしています。上記の参考ページでは100固定でコーディングされていましたので変えられるように設定しました。
パラメータ名はアンダースコアなしの「postperpage」にしてあります。
ひとつのカテゴリーに100個以上の記事が紐づいている場合は数値を増やさないと途中までしか出力されませんので、ご注意ください。

[sitemap postperpage=150]
※上記[]は全角になっていますので、そのままコピペはできません。

それからカテゴリーの表示順ですが、折角カテゴリーにこだわって改修しているのですから、表示順もコントロールしようと考えました。
そのためカテゴリーはslugで並び替え、記事は作成日の昇順にしています。
※カテゴリーページでは記事は降順に表示されますが、サイトマップとしては古い記事が先頭に来た方が良いと考えました。

ただカテゴリーのソートキーをslugにしただけでは当然思った通りには並びません。

サイトマップでのカテゴリーの並びを制御するために

WP管理者の皆様はカテゴリーのslugをどのように設定されておりますでしょうか?
本サイトでは単純に名前を英語表記にしていたのですが、ひと手間をかけて、例えばホームがカテゴリーであればslugの先頭に「010000-」、つぎの親カテゴリーは「020000-」、そのサブカテゴリーの先頭であれば「020100-」、さらにそのサブカテゴリーの子カテゴリーの先頭は「020101-」という風に設定しています。
※本サイトでは、カテゴリーは3階層と決めていますので数字6桁とハイフォンを並び替えのキーにしました。
このひと手間で思い通りの並び順にしています。
確かに、こうすることでURLには番号付きのslugが表示されることにはなりますが、カテゴリーページのアドレスが直接人の目に触れる機会というのは多くないことと存じます。

まとめ-具体的な修正内容

ただし全体的にコーディングとしてはちょっとイマイチだとは思います。
一応再帰的呼び出しについては理解しているつもりですが、今回は使用していません。

その理由というか、言い訳というかは、経験値が浅いために、3階層目を「parent」のままで読みだすのか、今回のように「child_of」にした方が良いのか?の判断が付かなかったことと、本サイトを運用しているXserverでアプリケーションループをされてしまった場合の影響度が心配なので控えさせていただきました。

また、例えば記事が1,000もあるようなサイトになった場合にどうなってしまうのか?は一日1つ記事を書いたとしても後2年半近くしないと到達しないので、もう少し経ってから考えたいと思います。

以下がコーディングになりますが、毎度恐縮ではありますが自己責任でのご利用でお願いします。

//サイトマップショートコード
add_shortcode('sitemap', 'sitemap_shortcode');
if ( !function_exists( 'sitemap_shortcode' ) ):
function sitemap_shortcode( $atts, $content = null ) {
  extract( shortcode_atts( array(
    'page' => 1,
    'single' => 0,
    'category' => 1,
    'archive' => 0,
    'postsperpage' => 100,
  ), $atts ) );
  ob_start();?>
  <div class="sitemap">
    <?php if ($page): ?>
    <h4>固定ページ</h4>
    <ul>
      <?php wp_list_pages('title_li='); ?>
    </ul>
    <?php endif; ?>
    <?php if ($single): ?>
    <h4>記事一覧</h4>
    <ul>
      <?php wp_get_archives( 'type=alpha' ); ?>
    </ul>
    <?php endif; ?>
    <?php if ($category): ?>
    <h4>カテゴリー別</h4>
    <?php
      $args=array('parent' => 0,'orderby' => 'slug');
      $categories=get_categories($args);
      global $post;
      echo '<ul>';
      foreach( $categories as $category ) { 
        $x1categories = get_categories( 'parent=' . $category->term_id . '&orderby=slug' );
        $catnot = $category->term_id;
        foreach ( $x1categories as $x1category ) {
          $catnot = $catnot . ',-' . $x1category->term_id;
        }
        echo '<b><a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "%s" ), $category->name ) . '" ' . '>' . $category->name.'</a></b>';
        $myposts = get_posts('posts_per_page=' . $postsperpage . '&category=' . $catnot . '&order=ASC');
        echo '<ul>';
        foreach($myposts as $post) {
          setup_postdata($post);
          echo '<li><a href="' . get_the_permalink() . '">' . get_the_title() . '</a></li>';
        }
        echo '</ul>';
        if ($x1categories) {
          echo '<ul>';
          foreach ( $x1categories as $x1category ) {
            $y2categories = get_categories( 'parent=' . $x1category->term_id . '&orderby=slug' );
            $catnot = $x1category->term_id;
            foreach ( $y2categories as $y2category ) {
              $catnot = $catnot . ',-' . $y2category->term_id;
            }
            echo '<b><a href="' . get_category_link( $x1category->term_id ) . '" title="' . sprintf( __( "%s" ), $x1category->name ) . '" ' . '>' . $x1category->name.'</a></b>';
            echo '<ul>';
            $myposts = get_posts('posts_per_page=' . $postsperpage . '&category=' . $catnot . '&order=ASC');
            foreach($myposts as $post) {
              setup_postdata($post);
              echo '<li><a href="' . get_the_permalink() . '">' . get_the_title() . '</a></li>';
            }
            echo '</ul>';
            if ($y2categories) {
              echo '<ul>';
              foreach ( $y2categories as $y2category ) {
                $z3categories = get_categories( 'child_of=' . $y2category->term_id . '&orderby=slug' );
                $catnot = $y2category->term_id;
                foreach ( $z3categories as $z3category ) {
                  $catnot = $catnot . ',-' . $z3category->term_id;
                }
                echo '<b><a href="' . get_category_link( $y2category->term_id ) . '" title="' . sprintf( __( "%s" ), $y2category->name ) . '" ' . '>' . $y2category->name.'</a></b>';
                echo '<ul>';
                $myposts = get_posts('posts_per_page=' . $postsperpage . '&category=' . $catnot . '&order=ASC');
                foreach($myposts as $post) {
                  setup_postdata($post);
                  echo '<li><a href="' . get_the_permalink() . '">' . get_the_title() . '</a></li>';
                }
                echo '</ul>';
              }
              echo '</ul>';
            } //y2categories
          }
          echo '</ul>';
        } //x1categories
      }
      echo '</ul>';
      wp_reset_postdata(); //元々の$postに戻す
    ?>
    <?php endif; ?>
    <?php if ($archive): ?>
    <h4>月別アーカイブ</h4>
    <ul>
      <?php wp_get_archives('type=monthly'); ?>
    </ul>
    <?php endif; ?>
  </div>
  <?php
  return ob_get_clean();
}
endif;

以上ご報告申し上げます。

p.s. 2019/3/11
(グローバル変数$postを元に戻していなかったために)上記ショートコードをいれた投稿の文末に表示されるカテゴリーが正しく表示されていませんでした。
それと合わせてglobal変数の宣言の場所をループ外にしました。
31行目と87行目が該当する箇所です。