BLOGブログ

  • 2025-01-20

【WordPress】プラグインなしでパンくずリストを生成する方法

今回はWordPressでプラグインをつかわずにパンくずリストを生成する方法をご紹介します。
サイトにパンくずを設置したいけど、プラグインをつかうまでもない・・・というような場合に参考にしていただければ。

パンくずを設置する方法

functions.php

まず、functions.phpに以下をコピペします。

if ( ! function_exists( 'custom_breadcrumb' ) ) {
  function custom_breadcrumb() {

    // トップページでは何も出力しないように
    if ( is_front_page() ) return false;

    //そのページのWPオブジェクトを取得
    $wp_obj = get_queried_object();

    echo '<div id="breadcrumb">'.  //id名などは任意で
      '<ul>'.
        '<li>'.
          '<a href="'. esc_url( home_url() ) .'"><span>ホーム</span></a>'.
        '</li>';

    if ( is_attachment() ) {

      /**
       * 添付ファイルページ ( $wp_obj : WP_Post )
       * ※ 添付ファイルページでは is_single() も true になるので先に分岐
       */
      $post_title = apply_filters( 'the_title', $wp_obj->post_title );
      echo '<li><span>'. esc_html( $post_title ) .'</span></li>';

    } elseif ( is_single() ) {

      /**
       * 投稿ページ ( $wp_obj : WP_Post )
       */
      $post_id    = $wp_obj->ID;
      $post_type  = $wp_obj->post_type;
      $post_title = apply_filters( 'the_title', $wp_obj->post_title );

      // カスタム投稿タイプかどうか
      if ( $post_type !== 'post' ) {

        $the_tax = "";  //そのサイトに合わせて投稿タイプごとに分岐させて明示的に指定してもよい

        // 投稿タイプに紐づいたタクソノミーを取得 (投稿フォーマットは除く)
        $tax_array = get_object_taxonomies( $post_type, 'names');
        foreach ($tax_array as $tax_name) {
            if ( $tax_name !== 'post_format' ) {
                $the_tax = $tax_name;
                break;
            }
        }

        $post_type_link = esc_url( get_post_type_archive_link( $post_type ) );
        $post_type_label = esc_html( get_post_type_object( $post_type )->label );

        //カスタム投稿タイプ名の表示
        echo '<li>'.
              '<a href="'. $post_type_link .'">'.
                '<span>'. $post_type_label .'</span>'.
              '</a>'.
            '</li>';

        } else {

          $the_tax = 'category';  //通常の投稿の場合、カテゴリーを表示

        }

        // 投稿に紐づくタームを全て取得
        $terms = get_the_terms( $post_id, $the_tax );

        // タクソノミーが紐づいていれば表示
        if ( $terms !== false ) {

          $child_terms  = array();  // 子を持たないタームだけを集める配列
          $parents_list = array();  // 子を持つタームだけを集める配列

          //全タームの親IDを取得
          foreach ( $terms as $term ) {
            if ( $term->parent !== 0 ) {
              $parents_list[] = $term->parent;
            }
          }

          //親リストに含まれないタームのみ取得
          foreach ( $terms as $term ) {
            if ( ! in_array( $term->term_id, $parents_list ) ) {
              $child_terms[] = $term;
            }
          }

          // 最下層のターム配列から一つだけ取得
          $term = $child_terms[0];

          if ( $term->parent !== 0 ) {

            // 親タームのIDリストを取得
            $parent_array = array_reverse( get_ancestors( $term->term_id, $the_tax ) );

            foreach ( $parent_array as $parent_id ) {
              $parent_term = get_term( $parent_id, $the_tax );
              $parent_link = esc_url( get_term_link( $parent_id, $the_tax ) );
              $parent_name = esc_html( $parent_term->name );
              echo '<li>'.
                    '<a href="'. $parent_link .'">'.
                      '<span>'. $parent_name .'</span>'.
                    '</a>'.
                  '</li>';
            }
          }

          $term_link = esc_url( get_term_link( $term->term_id, $the_tax ) );
          $term_name = esc_html( $term->name );
          // 最下層のタームを表示
          echo '<li>'.
                '<a href="'. $term_link .'">'.
                  '<span>'. $term_name .'</span>'.
                '</a>'.
              '</li>';
        }

        // 投稿自身の表示
        echo '<li><span>'. esc_html( strip_tags( $post_title ) ) .'</span></li>';

    } elseif ( is_page() || is_home() ) {

      /**
       * 固定ページ ( $wp_obj : WP_Post )
       */
      $page_id    = $wp_obj->ID;
      $page_title = apply_filters( 'the_title', $wp_obj->post_title );

      // 親ページがあれば順番に表示
      if ( $wp_obj->post_parent !== 0 ) {
        $parent_array = array_reverse( get_post_ancestors( $page_id ) );
        foreach( $parent_array as $parent_id ) {
          $parent_link = esc_url( get_permalink( $parent_id ) );
          $parent_name = esc_html( get_the_title( $parent_id ) );
          echo '<li>'.
                '<a href="'. $parent_link .'">'.
                  '<span>'. $parent_name .'</span>'.
                '</a>'.
              '</li>';
        }
      }
      // 投稿自身の表示
      echo '<li><span>'. esc_html( strip_tags( $page_title ) ) .'</span></li>';

    } elseif ( is_post_type_archive() ) {

      /**
       * 投稿タイプアーカイブページ ( $wp_obj : WP_Post_Type )
       */
      echo '<li><span>'. esc_html( $wp_obj->label ) .'</span></li>';

    } elseif ( is_date() ) {

      /**
       * 日付アーカイブ ( $wp_obj : null )
       */
      $year  = get_query_var('year');
      $month = get_query_var('monthnum');
      $day   = get_query_var('day');

      if ( $day !== 0 ) {
        //日別アーカイブ
        echo '<li>'.
              '<a href="'. esc_url( get_year_link( $year ) ) .'"><span>'. esc_html( $year ) .'年</span></a>'.
            '</li>'.
            '<li>'.
              '<a href="'. esc_url( get_month_link( $year, $month ) ) . '"><span>'. esc_html( $month ) .'月</span></a>'.
            '</li>'.
            '<li>'.
              '<span>'. esc_html( $day ) .'日</span>'.
            '</li>';

      } elseif ( $month !== 0 ) {
        //月別アーカイブ
        echo '<li>'.
              '<a href="'. esc_url( get_year_link( $year ) ) .'"><span>'. esc_html( $year ) .'年</span></a>'.
            '</li>'.
            '<li>'.
              '<span>'. esc_html( $month ) .'月</span>'.
            '</li>';

      } else {
        //年別アーカイブ
        echo '<li><span>'. esc_html( $year ) .'年</span></li>';

      }

    } elseif ( is_author() ) {

      /**
       * 投稿者アーカイブ ( $wp_obj : WP_User )
       */
      echo '<li><span>'. esc_html( $wp_obj->display_name ) .' の執筆記事</span></li>';

    } elseif ( is_archive() ) {

      /**
       * タームアーカイブ ( $wp_obj : WP_Term )
       */
      $term_id   = $wp_obj->term_id;
      $term_name = $wp_obj->name;
      $tax_name  = $wp_obj->taxonomy;

      /* ここでタクソノミーに紐づくカスタム投稿タイプを出力しても良いでしょう。 */

      // 親ページがあれば順番に表示
      if ( $wp_obj->parent !== 0 ) {

        $parent_array = array_reverse( get_ancestors( $term_id, $tax_name ) );
        foreach( $parent_array as $parent_id ) {
          $parent_term = get_term( $parent_id, $tax_name );
          $parent_link = esc_url( get_term_link( $parent_id, $tax_name ) );
          $parent_name = esc_html( $parent_term->name );
          echo '<li>'.
                '<a href="'. $parent_link .'">'.
                  '<span>'. $parent_name .'</span>'.
                '</a>'.
              '</li>';
        }
      }

      // ターム自身の表示
      echo '<li>'.
            '<span>'. esc_html( $term_name ) .'</span>'.
          '</li>';


    } elseif ( is_search() ) {

      /**
       * 検索結果ページ
       */
      echo '<li><span>「'. esc_html( get_search_query() ) .'」で検索した結果</span></li>';

    
    } elseif ( is_404() ) {

      /**
       * 404ページ
       */
      echo '<li><span>お探しの記事は見つかりませんでした。</span></li>';

    } else {

      /**
       * その他のページ(無いと思うけど一応)
       */
      echo '<li><span>'. esc_html( get_the_title() ) .'</span></li>';

    }

    echo '</ul></div>';  // 冒頭に合わせた閉じタグ

  }
}

パンくずを設置したい箇所

次に、パンくずを設置したい箇所に以下をコピペしてください。
テンプレートファイル以外(編集画面など)に設置したい場合は、ショートコードやインクルードでつかっても問題ありません。

<?php custom_breadcrumb(); ?>

出力されたソースをCSSで整形する

以上の方法で出力されたパンくずは、<div id=”breadcrumb”>で囲まれたulとliのリストタグで吐き出されているはずです。
あとは、このリストをCSSできれいにしてあげれば完成です。
ちなみに僕はliをfloatで横並びにするので、親タグのulにclearfixのclassを付け加えてつかっています。

パンくずリストの重要性

WEBサイトのパンくずリストは、ユーザーのナビゲーションを助ける重要な要素です。
特に複雑な構造を持つサイトでは、パンくずリストが役立ちます。

ユーザーの利便性向上

パンくずリストは、ユーザーが現在どのページにいるのかを一目で理解できるようにし、サイト内の他の関連ページに簡単に移動できる手助けをします。
特に階層構造が深いサイトでは、パンくずリストがあることで迷子になることを防ぎ、ユーザーの行動がスムーズになります。

サイトの階層構造の視覚化

パンくずリストは、サイトのコンテンツや情報の階層構造を視覚的に示すため、ユーザーがどの位置にいるのか、またどのようにページを辿ってきたのかを把握する助けになります。
これにより、ユーザーが他のカテゴリや関連ページに移動する際の手間を減らすことができます。

SEO(検索エンジン最適化)の向上

パンくずリストは、SEOにおいても重要な要素です。
検索エンジンはサイト内のリンク構造を評価する際、パンくずリストを参照することがあります。
パンくずリストによって、ページ間のリンクが明確に示され、Googleなどの検索エンジンがサイトをより効率的にクロールできるようになります。
また、検索結果においてもパンくずリストが表示されることがあり、ユーザーがサイトを訪れる際に、どのページにアクセスするかの参考にもなります。

ユーザーエクスペリエンス(UX)の向上

パンくずリストは、特に多くのページやカテゴリーを持つ大規模なサイトにおいて、ユーザーエクスペリエンスを大きく改善します。
ユーザーは迷うことなく簡単に他のページにアクセスでき、サイト全体を把握しやすくなります。
このようなUXの向上は、サイトの利用時間の延長や直帰率の低下にも繋がります。

モバイルフレンドリーなサイト設計

パンくずリストは、モバイルデバイスでも特に有用です。
画面が小さいため、メニューやナビゲーションが限られている場合でも、パンくずリストを使うことでユーザーは効率的にページ間を移動できるようになります。
多くのモバイルサイトでは、パンくずリストがコンパクトに表示され、スムーズなナビゲーションをサポートします。

コンバージョン率の向上

ユーザーがサイト内で迷子になったり、目的の情報に辿り着けなかったりすると、離脱率が高くなります。
パンくずリストを設置することで、ユーザーが簡単にサイト内を移動できるため、離脱を減らし、コンバージョン率(購入や問い合わせなど)を向上させる可能性があります。