サポート » 使い方全般 » プラグイン無しでパンくずリストを出力させる方法

  • プラグイン無しでパンくずリストを出力させたいのですが
    検索するとほぼ同じコードが記述されたサイトがヒットします。

    以下例

    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>';  // 冒頭に合わせた閉じタグ
      }
    }
    

    上記コードの場合、固定ページの一つを投稿ページに設定するとそのページがパンくずリストに表示されなくなります。
    (例えばsample.com/blogというページを作り、ページタイトルがブログ記事とする)

    〇表示したい形
    sample.com/blog(ブログ記事)/カテゴリ/投稿ページ

    パンくず HOME→ブログ記事→カテゴリ→投稿ページ

    〇実際の表示
    sample.com/blog(ブログ記事)/カテゴリ/投稿ページ

    パンくず HOME→カテゴリ→投稿ページ

    「Breadcrumb NavXT」プラグインを使えば希望通りの表示になるのですが、先のコードだと何か足りない条件分岐があるのでしょうか?

    質問内容が分かり難いかも知れませんが、何か良い案がありましたらご教示お願い致します。

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • ざっと見た感じでは、ブログ投稿インデックスには対応していないようです。自前で出力するようにする必要がありそうです。

    ブログ投稿インデックスは get_option( 'page_for_posts' ) で取得することができます。あとは、投稿ページの処理の前に他の処理と同じように出力するようにすればいいかと思います。

    サンプルコードを書いてみました。

    if ( $wp_obj->post_type === 'post' && $page_for_posts = get_option( 'page_for_posts' ) ) {
    	echo '<li><a href="' . esc_url( get_permalink( $page_for_posts ) ) . '"><span>'. get_the_title( $page_for_posts ) . '</span></a></li>';
    }
    トピック投稿者 torasan

    (@torasan)

    ishitaka様

    ご丁寧に回答頂き有難うございます。

    サンプルコードを試したところ、希望通りのパンくずリストが表示されました。

    差し支えなければもう一つご回答いただけると助かるのですが、

    パンくず HOME→ブログ記事

    となった時にパンくずの最後(ブログ記事)をaタグ無しにすることは可能でしょうか?

    今は

    パンくず HOME(リンクあり)→ブログ記事(リンクあり)

    ですが、これを

    パンくず HOME(リンクあり)→ブログ記事(リンクなし)

    という形にしたいと思います。

    サンプルコードでもパンくずの終わりはリンク無しを出力するようになっていて、
    コードを見るとforeachで末尾がそうでないかを判定している(?)ように見えるのですが、ちょっと分かりませんでした。

    つまり、

    パンくず HOME→ブログ記事(リンクあり)→カテゴリ→投稿ページ

    パンくず HOME→ブログ記事(リンクなし)

    というのを実現したいと考えております。

    アドバイス頂ければ幸いです。

    パンくず HOME→ブログ記事(リンクなし)

    この場合の条件がわかりません。どのような場合(ページ?)でしょうか?

    トピック投稿者 torasan

    (@torasan)

    パンくず HOME(リンクあり)→ブログ記事(リンクなし)
    この場合の条件がわかりません。どのような場合(ページ?)でしょうか?

    ishitaka様、返信内容が分かり難くてすみません。

    sample.com/blog(ブログ記事)/

    を表示した場合です。
    つまりブログ記事のアーカイブページになります。

    現状は、

    HOME(sample.com リンクあり)→ブログ記事(blog リンクあり)

    なので、

    パンくずリストの最後のページタイトル部分をリンク無しに出来ないものかと。。。

    ご理解頂けましたでしょうか?

    ブログ投稿インデックスの場合、リンクなしで表示されると思うのですが・・・?
    コードはどこ(} elseif ( is_single() ) { のブロック内?)に追加しましたか?

    トピック投稿者 torasan

    (@torasan)

    ishitaka様

    お世話になります。

    ※返信がスパム判定されたので再送です

    どうもキャッシュの関係でリンクに色がついていたようです。。。

    コードはどこ(} elseif ( is_single() ) { のブロック内?)に追加しましたか?

    '</li>';
    (ここに追加しました。)
        if ( is_attachment() ) {

    表示はされているので問題はないと思いますがいかがでしょうか?

    それから並行してパンくずリストの構造マークアップ化のためのコードをいじっているのですが

    以下

    if (!function_exists('custom_breadcrumb')) {
        function custom_breadcrumb($wp_obj = null)
        {$current_url = (empty($_SERVER['http']) ? 'http://' : 'https://') . $_SERVER['http_HOST'] . $_SERVER['REQUEST_URI'];
            $html = "";
            if (is_home() || is_front_page()) return false;
            $wp_obj = $wp_obj ?: get_queried_object();
            $position = 1;
            $html .= '<ul class="breadcrumb" itemscope itemtype="schema.org/BreadcrumbList">' .
                '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="home">' .
                '<a itemprop="item" href="' . home_url() . '">' .
                '<span itemprop="name">HOME</span>' .
                '<meta itemprop="position" content="' . $position . '" />' .
                '</a>' .
                '</li>';
            $position++;
    if ( $wp_obj->post_type === 'post' && $page_for_posts = get_option( 'page_for_posts' ) ) {
                    $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                        '<a itemprop="item"  href="' . get_the_permalink( $page_for_posts ) . '">' .
                        '<span itemprop="name">' . get_the_title( $page_for_posts ) . '</span>' .
                        '<meta itemprop="position" content="' . $position . '" />' .
                        '</a>' .
                        '</li>';
                    $position++;
    }
    
            if (is_attachment()) {
                /**
                 * 添付ファイルページ ( $wp_obj : WP_Post )
                 * ※ 添付ファイルページでは is_single() も true になるので先に分岐
                 */
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="current">' .
                    '<span itemprop="name">' . $wp_obj->post_title . '</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</li>';
            } elseif (is_single()) {
               /**
                 * 投稿ページ ( $wp_obj : WP_Post )
                 */
                $post_id = $wp_obj->ID;
                $post_type = $wp_obj->post_type;
                $post_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;
                        }
                    }
                    //カスタム投稿タイプ名の表示
                    $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                        '<a itemprop="item"  href="' . get_post_type_archive_link($post_type) . '">' .
                        '<span itemprop="name">' . get_post_type_object($post_type)->label . '</span>' .
                        '<meta itemprop="position" content="' . $position . '" />' .
                        '</a>' .
                        '</li>';
                    $position++;
                } else {
        $the_tax = 'category';//通常の投稿の場合、カテゴリーを表示
                }
                // タクソノミーが紐づいていれば表示
                if ($the_tax !== "") {
                    $child_terms = array(); // 子を持たないタームだけを集める配列
                    $parents_list = array(); // 子を持つタームだけを集める配列
                    // 投稿に紐づくタームを全て取得
                    $terms = get_the_terms($post_id, $the_tax);
                    if (!empty($terms)) {
                        //全タームの親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);
                                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .                                '<a itemprop="item" href="' . get_term_link($parent_id, $the_tax) . '">' .
                                    '<span itemprop="name">' . $parent_term->name . '</span>' .
                                    '<meta itemprop="position" content="' . $position . '" />' .
                                    '</a>' .
                                    '</li>';
                                $position++;
                            }
                        }
                        // 最下層のタームを表示
                        $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                            '<a itemprop="item" href="' . get_term_link($term->term_id, $the_tax) . '">' .
                            '<span itemprop="name">' . $term->name . '</span>' .
                            '<meta itemprop="position" content="' . $position . '" />' .
                            '</a>' .
                            '</li>';
                        $position++;
                    }
                }
                // 投稿自身の表示
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="current">' .
                    '<a itemprop="item" href="' . $current_url . '" class="disabled">' .
                    '<span itemprop="name">'. $post_title .'</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</a>' .
                    '</li>';
            } elseif (is_page()) {
                /**
                 * 固定ページ ( $wp_obj : WP_Post )
                 */
                $page_id = $wp_obj->ID;
                $page_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) {
                        $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                            '<a itemprop="item" href="' . get_permalink($parent_id) . '">' .
                            '<span  itemprop="name">' . get_the_title($parent_id) . '</span>' .
                            '<meta itemprop="position" content="' . $position . '" />' .
                            '</a>' .
                            '</li>';
                        $position++;
                    }
                }
                // 投稿自身の表示
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="current">' .                '<a itemprop="item" href="' . $current_url . '" class="disabled">' .
                    '<span itemprop="name">' . $page_title . '</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</a>' .
                    '</li>';
            } elseif (is_post_type_archive()) {
                /**
                 * 投稿タイプアーカイブページ ( $wp_obj : WP_Post_Type )
                 */
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                    '<a itemprop="item" href="' . $current_url . '" class="disabled">' .
                    '<span itemprop="name">' . $wp_obj->label . '</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</a>' .
                    '</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);
                        $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                            '<a itemprop="item" href="' . get_term_link($parent_id, $tax_name) . '">' .
                            '<span itemprop="name">' . $parent_term->name . '</span>' .
                            '<meta itemprop="position" content="' . $position . '" />' .
                            '</a>' .
                            '</li>';
                        $position++;
                    }
                }
                // ターム自身の表示
    $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="current">' .                '<a itemprop="item" href="' . $current_url . '" class="disabled">' .
                    '<span itemprop="name">' . $term_name . '</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</a>' .
                    '</li>';
            } elseif (is_search()) {
                /**
                 * 検索結果ページ
                 */
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="current">' .
                    '<span itemprop="name">「' . get_search_query() . '」で検索した結果</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</li>';
            } elseif (is_404()) {
                /**
                 * 404ページ
                 */
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem" class="current">' .
                    '<span itemprop="name">お探しの記事は見つかりませんでした。</span>' .
                    '<meta itemprop="position" content="' . $position . '" />' .
                    '</li>';
            } else {
                /**
                 * その他のページ
                 */
                $html .= '<li itemprop="itemListElement" itemscope itemtype="schema.org/ListItem">' .
                    '<span itemprop="name">' . get_the_title() . '</span>' .
                    '</li>';
            }
            $html .= '</ul>'; 
            return $html;
        }
    }
    

    こんな感じにしても上手くいかないのですよねぇ…。

    sample.com/blog(ブログ記事)/カテゴリ/投稿ページ

    は問題ないのですが、

    sample.com/blog(ブログ記事)/

    に移動するとパンくずリストが表示されなくなります。

    トピック投稿者 torasan

    (@torasan)

    ishitaka様

    構造マークアップ化のためのコードについてですが
    2か所変更することで解決(多分)しました。

    変更前

    if (is_home() || is_front_page()) return false;

    変更後

    if (is_front_page()) return false;

    変更前

    } elseif (is_page()) {
                /**
                 * 固定ページ ( $wp_obj : WP_Post )
                 */

    変更後

    } elseif (is_page() || is_home() ) {
                /**
                 * 固定ページ ( $wp_obj : WP_Post )
                 */
    

    様々なアドバイスありがとうございました。

    トピック投稿者 torasan

    (@torasan)

    う~ん、解決したと思ったのですが、

    sample.com/blog(ブログ記事)/カテゴリ/

    に移動したときに

    パンくずが

    HOME→カテゴリ

    になってしまいますね。。。

    HOME→ブログ記事(blog)→カテゴリ

    になって欲しいのですが、中々難しいです…。

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • トピック「プラグイン無しでパンくずリストを出力させる方法」には新たに返信することはできません。