Mill's Note

【Wordpress Tips】パンくずリストの作り方

/

UIやSEOの為にも、サイトにパンくずリストは必須。

WordPressはプラグインで簡単に設置できますが、多すぎるプラグイン問題やもろもろ考えると、パンくず程度は自作にするっていうのもありですよね。

忘備録と改修実験を兼ねて、当サイトで使用している自作パンくず(breadcrumb)のコードを掲載しました。

もちろんSchemaもバッチリ入れていますので、そのまま使うなり、改修して遊ぶなり、突っ込みを入れるなり、ご自由にお使いください^^

自作パンくず(breadcrumb) の使い方

  1. 下のコードをコピペしてbreadcrumb.php として保存 (/inc/フォルダを作ってまとめるとメンテが楽です^^)
  2. 必要に応じ出力不要ページを記載 if(is_front_page() || is_page('〇〇')) のように繋ぎます
  3. functions.php に 以下のコードを記載して、作成したbreadcrumb.php を読み込みます
include_once get_template_directory() . '/inc/breadcrumb.php';
  1. header.php など、置きたい位置に<?php my_bread(); ?> と記載
    breadcrumb.php で除外ページを追加しないで、ここで分岐してもOKです^^

これでSchema付のパンくずが表示されます。
別ファイルにする場合は、最初の <?php をお忘れなく^^

カスタム投稿関係の設定は入れていませんので、カスタム投稿ページなどはエラーが出る可能性があります。
(そのうち追加する??かも??)

それ以外のページは設置コードを入れれば、自動的に表示されるようにしています。

自作パンくず(breadcrumb) コード

極力シンプルに作ったつもりがページ番号を入れたりして、結構長くなってしまいました。
Schemaは仕方ないにせよ、もっとスッキリさせたいなぁ・・・

PHP
<?php /* functions.php に直接書き込む場合はこの行を削除 */
if ( !function_exists('my_bread') ) { function my_bread() {

  /*  出力不要ページを記載 ------------------------  */
  if(is_front_page())  return;

  /*  出力設定 ---------------------------------  */
  $wp_obj = get_queried_object();
  $bread = '';
  $bread = '
<div class="breadcrumb">
  <ol itemscope itemtype="http://schema.org/BreadcrumbList">
    <li class="home" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a href="'.home_url( '/' ).'" itemprop="item" title="'. get_bloginfo( 'name' ) .' トップページ"><span itemprop="name">HOME</span></a>
      <meta itemprop="position" content="1">
    </li>'.PHP_EOL;

  /*  投稿ページ ---------------------------------  */
  if ( is_single() ) {
    $id = $wp_obj->ID;
    $title = apply_filters( 'the_title', $wp_obj->post_title );
    $post_tax = 'category'; 

    $terms = get_the_terms( $id, $post_tax );
    if ( $terms !== false ) {

      $family_terms = array(); //親を持つタームの親リスト取得
      foreach ( $terms as $term ) {
        if ( $term->parent !== 0 ) { $family_terms[] = $term->parent; }
      }

      $only_terms = array(); //最下層ターム(親リストに含まれないターム)を取得
      foreach ( $terms as $term ) {
        if ( !in_array( $term->term_id, $family_terms ) ) { $only_terms[] = $term; }
      }
      $term = $only_terms[0]; //最下層タームを1個のみ取得

      if ( $term->parent !== 0 ) { //最下層タームが親を持っていたら親を表示
        $parents = array_reverse( get_ancestors( $term->term_id, $post_tax ) );
        foreach ( $parents as $parent ) {
          $parent_term = get_term( $parent, $post_tax );
          $parent_link = esc_url( get_term_link( $parent, $post_tax ) );
          $parent_name = esc_html( $parent_term->name );
          $i = 2;
          $bread .='
    <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a href="'. $parent_link .'" itemprop="item"><span itemprop="name">' . $parent_name . '</span></a>
      <meta itemprop="position" content="'. $i++ .'">
    </li>'.PHP_EOL;
        }
      }

      //最下層タームを表示
      $term_link = esc_url( get_term_link( $term->term_id, $post_tax ) );
      $term_name = esc_html( $term->name );
      if ( $term->parent == 0 ) { $i = 2; }
      $bread .= '
    <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a href="'. $term_link .'" itemprop="item"><span itemprop="name">' . $term_name . '</span></a>
      <meta itemprop="position" content="'. $i++ .'">
    </li>'.PHP_EOL;
    }
    $bread .= '
    <li><span>' . esc_html( strip_tags( $title ) ) . '</span></li>'.PHP_EOL;

  /*  固定ページ ---------------------------------  */
  } elseif ( is_page() ) {

    $id = $wp_obj->ID;
    $title = apply_filters( 'the_title', $wp_obj->post_title );
    $paged = get_query_var( 'page' );
    $paged = $paged == 0 ? 1 : $paged;
    $page_no = $paged >= 2 ? ' (' . $paged . 'ページ目)' : '';

    if ( $wp_obj->post_parent !== 0 ) { // 親ページがあれば順番に表示
      $parents = array_reverse( get_post_ancestors( $id ) );
      foreach ( $parents as $parent ) {
        $parent_link = esc_url( get_permalink( $parent ) );
        $parent_name = esc_html( get_the_title( $parent ) );
        $i = 2;
        $bread .= '
     <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a href="'. $parent_link .'" itemprop="item"><span itemprop="name">' . $parent_name . '</span></a>
      <meta itemprop="position" content="'. $i++ .'">
    </li>'.PHP_EOL;
      }
    }
    $bread .= '
    <li><span>' . esc_html( strip_tags( $title ) ) . '</span>' . $page_no . '</li>'.PHP_EOL;

  /*  ターム ---------------------------------  */
  } elseif ( is_archive() ) {

    $term_id = $wp_obj->term_id;
    $term_name = $wp_obj->name;
    $tax_name = $wp_obj->taxonomy;
    
    $paged = get_query_var( 'paged' );
    $paged = $paged == 0 ? 1 : $paged;
    $paged = ' (' . $paged . 'ページ目)';
    global $wp_query;
    $max_pages = $wp_query->max_num_pages;
    $page_no = $max_pages > 1 ? $paged : '';

    if ( $wp_obj->parent !== 0 ) { // 親ページがあれば順番に表示
      $parents = array_reverse( get_ancestors( $term_id, $tax_name ) );

      foreach ( $parents as $parent ) {
        $parent_term = get_term( $parent, $tax_name );
        $parent_link = esc_url( get_term_link( $parent, $tax_name ) );
        $parent_name = esc_html( $parent_term->name );
        $i = 2;
        $bread .=
          '
     <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
      <a href="'. $parent_link .'" itemprop="item"><span itemprop="name">' . $parent_name . '</span></a>
      <meta itemprop="position" content="'. $i++ .'">
    </li>'.PHP_EOL;
      }
    }
    $bread .= '
    <li><span>' . esc_html( $term_name ) . '</span> ' . esc_html( $page_no ) . '</li>'.PHP_EOL;

  } elseif ( is_search() ) { /*  検索結果  */
    $bread .= '
    <li><span>[' . esc_html( get_search_query() ) . ']の検索結果</span></li>'.PHP_EOL;

  } elseif ( is_404() ) { /*  404  */
    $bread .= '
    <li><span>Not Found</span></li>'.PHP_EOL;

  } else { /*  その他のページ(一応)  */
    $bread .= '
    <li><span>' . esc_html( get_the_title() ) . '</span></li>'.PHP_EOL;
  }
  $bread .= '
  </ol>
</div>'.PHP_EOL;

echo $bread;
} }