【WordPress】プラグインなしでパンくずリストを実装する方法|階層対応・構造化データの注意まで

パンくずリストは、訪問者に現在地を示しサイト構造を伝えるナビゲーションです。この記事では、プラグインを使わずに functions.php の関数だけでパンくずリストを実装する方法を解説します。

自作の前に:テーマ内蔵の確認を
Cocoon をはじめ多くのテーマにはパンくずリスト機能が内蔵されています(Cocoonは設定から表示位置を選ぶだけ・構造化データも自動出力)。Yoast SEO などのプラグインにも同機能があります。テーマ内蔵 → プラグイン → 自作の順で検討し、細かい制御が必要な場合に自作を選ぶのがおすすめです。
この記事でわかること

  • ページ種別ごとに出し分けるパンくず関数の作成(カテゴリー・固定ページ階層・タグ・検索)
  • テーマへの組み込みとCSS
  • リッチリザルトに必要な構造化データ(BreadcrumbList)の注意
スポンサーリンク

パンくずリストの関数を作成する

functions.php に次の関数を追加します。区切り文字は $sep にまとめ、URLは esc_url()・テキストは esc_html() でエスケープして出力します。固定ページは get_post_ancestors()親ページの階層も辿ります。

functions.php:パンくずリスト生成関数
function custom_breadcrumbs() {
  $sep = ' » '; // 区切り文字(ここを変えれば一括変更)

  echo '<a href="' . esc_url(home_url('/')) . '">ホーム</a>';

  if (is_single()) {
    // 投稿:先頭のカテゴリー → 記事タイトル
    $cats = get_the_category();
    if (!empty($cats)) {
      echo $sep . '<a href="' . esc_url(get_category_link($cats[0]->term_id)) . '">'
        . esc_html($cats[0]->name) . '</a>';
    }
    echo $sep . esc_html(get_the_title());
  } elseif (is_page()) {
    // 固定ページ:親ページの階層を上から辿る
    $ancestors = array_reverse(get_post_ancestors(get_the_ID()));
    foreach ($ancestors as $ancestor_id) {
      echo $sep . '<a href="' . esc_url(get_permalink($ancestor_id)) . '">'
        . esc_html(get_the_title($ancestor_id)) . '</a>';
    }
    echo $sep . esc_html(get_the_title());
  } elseif (is_category()) {
    echo $sep . esc_html(single_cat_title('', false));
  } elseif (is_tag()) {
    echo $sep . esc_html(single_tag_title('', false));
  } elseif (is_search()) {
    echo $sep . '検索結果:' . esc_html(get_search_query());
  } elseif (is_date()) {
    echo $sep . esc_html(get_the_time('Y年n月')) . 'の記事';
  }
}
カテゴリーは「1系統」に絞る
投稿に複数カテゴリーがある場合、パンくずでは先頭の1つに絞るのが一般的です(すべて並べると「現在地」の意味が薄れます)。カテゴリー取得の詳細は記事のカテゴリーを取得する方法(完全ガイド)、リンク付き表示の基本は特定のカテゴリー名をリンク付きで表示する方法を参照してください。

テーマに組み込む

表示したいテンプレート(header.php など)で関数を呼び出します。トップページでは非表示にするのが一般的です(is_front_page() と is_home() の違いも参照)。

テンプレート:フロントページ以外で表示
<?php if (!is_front_page()) : ?>
  <div class="breadcrumbs">
    <?php custom_breadcrumbs(); ?>
  </div>
<?php endif; ?>

CSSで見た目を整える

style.css:パンくずのスタイル
.breadcrumbs {
  padding: 10px 0;
  font-size: 14px;
  color: #666;
}

.breadcrumbs a {
  color: #0073aa;
  text-decoration: none;
}

.breadcrumbs a:hover {
  text-decoration: underline;
}

注意:リッチリザルトには構造化データが必要

自作パンくずはそのままでは検索結果に反映されない
Google検索結果のパンくず表示(リッチリザルト)には、schema.org の BreadcrumbList 構造化データが必要です。YoastやCocoon内蔵のパンくずは自動で出力しますが、自作の場合は自分で追加する必要があります。Cocoon利用中なら内蔵パンくず(構造化データ込み)を活かし、見た目だけ自作したい場合も構造化データはテーマ側に任せるのが手軽です。

BreadcrumbList は次のようなJSON-LD形式です(例:ホーム → カテゴリー → 記事)。PHPで動的に出力する実装はテーマにJSON-LD形式の構造化データを追加する方法で詳しく解説しています。

JSON-LD:BreadcrumbListの構造(例)
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "ホーム", "item": "https://example.com/" },
    { "@type": "ListItem", "position": 2, "name": "WordPress", "item": "https://example.com/wp/" },
    { "@type": "ListItem", "position": 3, "name": "記事タイトル" }
  ]
}

よくある質問(FAQ)

Q区切り文字(» や / など)を変更するには?
Aこの記事のコードでは $sep 変数を書き換えるだけで全箇所に反映されます。HTML側で区切りを持たせている場合は、CSSの疑似要素(.breadcrumbs a + a::before { content: " / "; } など)で変える方法もあります。
Q自作パンくずでも検索結果にパンくずが表示されますか?
AHTML のパンくずだけでは表示されません。BreadcrumbList の構造化データ(JSON-LD)を出力する必要があります。テーマやSEOプラグインが出力している場合は不要です。自作する場合はJSON-LDを追加する方法を参照してください。
Qテーマ内蔵・プラグイン・自作、どれを使うべきですか?
Aテーマ内蔵 → プラグイン → 自作の順で検討するのがおすすめです。Cocoonなど内蔵機能があれば構造化データ込みで手間がありません。表示内容や階層を細かく制御したい場合に、この記事の自作方式が向いています。

まとめ

  • 関数:ページ種別ごとに分岐し、esc_url / esc_html で安全に出力
  • 階層:固定ページは get_post_ancestors()、投稿はカテゴリー1系統
  • 組み込み!is_front_page() でトップ以外に表示
  • SEO:リッチリザルトには BreadcrumbList 構造化データが別途必要
  • 判断順:テーマ内蔵(Cocoon等)→ プラグイン → 自作

自作は自由度が高いぶん、構造化データまで含めて自分で管理することになります。テーマ内蔵機能との使い分けを踏まえて実装しましょう。