【WordPress】パンくずリストを自作で実装して階層リンクを表示させる方法

パンくずリストは家に帰るための道しるべ。いろんなところで役に立つので、早めに実装してしまいましょう。

多くのWebサイトには、現在見ているページはどこなのか?(自分はそのサイトのどこにいるのか?) をナビしてくれる「パンくずリスト」というものが設置されています。

これは必要なものだからこそ設置されているのですが、ブログを運営するツールがWordPressの場合、テーマによってはパンくずリストは最初から使うことはできません。

そこで、今回はこのパンくずリストを、WordPressに自作で(プラグインなしで)実装する方法をご紹介していきます。

また、この機能は「構造化データ」といって、検索結果にもかかわる部分があります。それへの対応も、あわせて確認しておくことにしましょう。

目次

パンくずリストの役割とその必要性

ブログ記事のタイトル上部に設置されたパンくずリスト

パンくずリストとは、記事タイトルの上部に設置された、そのサイトにおけるユーザーの位置(現在地)をしめした地図のようなものをいいます。

大なり記号(>)、二重の不等号(>>)、矢印(→)、などが区切りとして使用され、「ホーム → カテゴリー名 → 見ている記事名」といった、階層型のリンクが表示されるようになるものです。

その目的は、もちろん、ユーザビリティ(利便性)のアップ。

見ている記事からトップページまでの階層リンクが表示されるようになることで、ユーザーは、自分がどこにいるのかをつかみやすくなります。クリックで上位の階層へもどることもできるようになるのです。

そもそも、人はいそいでいるとき、検索結果に表示される情報はそこまで見ません。

いちおうパンくず的なものも検索画面に表示されますが、ほとんど記事のタイトルと抜粋文だけを見てクリックしている、なんてこともめずらしくはないでしょう。

記事上のパンくずリストは、そんなユーザーに、まずはブログの構造をなんとなく伝えることができるのです。

サイト回遊率アップの効果が見込める

ここまでの話ではあまりピンとこないかもしれませんが、これは、「デパートに食料品を買いに行ったとき」を例にするとわかりやすいかもしれません。

目的をおえて帰ろうとしたとき、「あ、そうだ」と、ついでに必要だったものを思い出すことはよくあります。食料品のついでに日用品も買って帰ろう……となることがあるわけです。

ではそんなとき、そのデパートが初めてだったらどうしますか?

日用品売り場の場所がわからなければ、あてもなく探しまわるのではなく、まずはフロアマップ(地図)を見て日用品売り場に移動しますよね?

パンくずリストは、それ(フロアマップ)とおなじこと。

もしユーザーが、なにかほかの情報もほしいと思ってくれたときには、これが案内として役に立ったりもするのです。

しらべごとをしているお客さんは、買い物客よりも時間にたいしてシビアです。必要な情報がほかにもあるかどうかを、だれもがわざわざ確認してくれるわけではありません。

適切な案内があることで、サイト回遊率・PV数・収益アップなど、いろんなメリットが出てくるようにもなるのです。

構造化データとSEO対策でのメリット

見た目やリンクの表示から、ユーザビリティの向上が見込めるパンくずリストですが、メリットはそれだけではありません。

この「地図」は、検索エンジンに記事を登録してくれるクローラー(巡回ロボット)にたいしても有効で、クローラーが記事にたどりつきやすくなるとされています。

「ホーム → カテゴリー → 目的の記事」と道順ができることで、いち早く記事を検索結果に表示させられる可能性が上がるのです。

また、それ以外のメリットについては、話が少々ややこしくなるので、すこしくわしく確認しておくことにしましょう。

リッチな地図でユーザーにも検索エンジンにもやさしく

このパンくずリストは、「構造化データ」といって、わかりやすくいうと、簡易的な地図ではなく、より専門的な地図として検索エンジンに登録してもらうこともできます。

これをする方法として、以下の3つをよく見かけますが、

  • schema.org
  • JASON-LD
  • vocabulary.org(これは2021年1月でサポート終了)

ひとまずここでは、スキーマとかジェイソンとかいうものを使っておけば、検索結果のパンくずリストがよりわかりやすくなる、といった認識を持っておいてください。

具体的にいうと、検索結果に表示されたパンくずリスト部分は、以下のように通常はURLがそのままの表記となっていますが、これが日本語表記に変わります。

URLがそのまま表記されたパンくずリスト

(※これはまだリッチリザルトが反映されてない)

あまり見られないかもしれませんが、検索結果にもきちんとしたパンくずリスト(リッチリザルトといいます)が表示されることで、まずはユーザーにとってやさしくなるということです。

また、Googleも以下を公表しているように、

Google 検索では、検索結果内のウェブページからの情報を分類する際に、ページの本文内のパンくずリスト マークアップを使用します。Google検索セントラル-パンくずリスト

パンくずリストをより専門的なものにすることで、SEO(検索エンジンからの評価)的な効果も期待できるようになります。

見た目だけのものではなく、中身までしっかりとしたリッチな地図(リッチリザルトのパンくずリスト)は、ユーザーにも検索エンジンにもやさしい、ということです。

パンくずリストのプラグインなしでの作り方

ここまでのとおり、パンくずリストは利便性のアップやSEO対策にもなるので、設置しておいたほうがいいといえます。

「なんだか面倒くさそうだから、いらないや(なくてもいいや)」なんてことをしていると、それだけで機会損失をまねくことになってしまいかねません。

デパートに地図がなければ、とくに気の早いお客さんは、イライラしてきてさっさと帰ってしまうのです!

では、どうすればこれを設置できるのか? というのが今回の話。

手軽なものにプラグインがありますが、基本的なファイルさえいじることができれば、これは自力でもできます。

よって、ここでは、プラグインなしでの実装の方法をご紹介しましょう。

パンくずリスト実装までの手順

パンくずリストをプラグインなしで実装する方法は、以下の3手順。

  1. 「functions.php」にコードを書き込む
  2. 「CSS(スタイルシート)」で調節
  3. 呼び出したいファイルをいじって呼び出す

基本はコピペでいけるので安心してください。

「functions.php」をいじったり、呼び出す場所のファイルをいじるのでバックアップは必須となりますが、コピペ3発で完了します。

作業にはファイルを操作する知識が必要となるので、そこがわからなければ、子テーマ(PHPファイル)の作り方と、CSSの使い方をさきに確認しておいてください。

それでは、じっさいの手順を見ていきましょう!

1. functions.phpにコードを書き込む

まずは「functions.php」に、パンくずリストをつくるコードを書き込みますが、私が参考にさせていただいたコードはかなり長いです。

以下のとおりです。

//パンくずリスト
if ( ! function_exists( 'custom_breadcrumb' ) ) {
function custom_breadcrumb() {

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

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

//JSON-LD用のデータを保持する変数
$json_array = array();

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

if ( is_attachment() ) {

//添付ファイルページ ( $wp_obj : WP_Post )
$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>';

//JSON-LDデータ
$json_array[] = array(
'id' => $post_type_link,
'name' => $post_type_label
);

} 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>';
//JSON-LDデータ
$json_array[] = array(
'id' => $parent_link,
'name' => $parent_name
);
}
}

$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>';
//JSON-LDデータ
$json_array[] = array(
'id' => $term_link,
'name' => $term_name
);
}

// 投稿自身の表示
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>';
//JSON-LDデータ
$json_array[] = array(
'id' => $parent_link,
'name' => $parent_name
);
}
}
// 投稿自身の表示
echo '<li><span>'. esc_html( strip_tags( $page_title ) ) .'</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>';
//JSON-LDデータ
$json_array[] = array(
'id' => $parent_link,
'name' => $parent_name
);
}
}

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

} else {

//その他のページ
echo '<li><span>'. esc_html( get_the_title() ) .'</span></li>';

}
echo '</ul>';

//JSON-LDの出力(2階層以上であれば)
if ( !empty( $json_array ) ) :
$pos = 1;
$json = '';
foreach ( $json_array as $data ) :
$json .= '{
"@type": "ListItem",
"position": '. $pos++ .',
"item": {
"@id": "'. $data['id'] .'",
"name": "'. $data['name'] .'"
}
},';
endforeach;

echo '<script type="application/ld+json">{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": ['. rtrim( $json, ',' ) .']
}</script>';
endif;

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

}
}

記事本文中とカテゴリーのページに設置したかったので、削れるところは削りましたが、全文は以下の参考記事で確認できます。

(参考:【JSON-LD対応】WordPressでプラグインを使わずにパンくずリストを自動で生成するコードを自作してみた

このコードは構造化データに対応しているもの(ジェイソン)なので、それもあって長くなっているようです。

ただ、コードは長くても、いちど書き込んでしまえば関係ないので、これはそこまで気にしなくてもいいかもしれません。

大なり記号(>)のまわりに半角スペースを入れるなどして、階層のあいだに余白をとっていますが、あとは参考にさせていただいたコードのままとなっています。

2. CSS(スタイルシート)で調整

縦並びになったパンくずリスト

つぎに、このままパンくずリストを設置すると、画像のように階層のリンクが横並びにならずに縦並びになってしまうので、これを修正します。

CSS(スタイルシート)に書くのはほんの数行で、以下のとおり。

/* パンくず位置調整 */
div#breadcrumb {
	margin:-25px 0 30px 0;/*余白*/
	font-size: 94%;/*文字サイズ*/
}

div#breadcrumb  ul li{
	display:inline;/*横並びにする*/
	line-height:20px;/*行間*/
}

コードの「breadcrumb(パンくず)」が「id」となっているので、スタイルの調節では「#」を使用しています。

余白・文字サイズ(これはpx指定も可)・行間の数値をいじれば、好みのデザインになると思います。

ここはあとで自由にいじってみてください。

3. パンくずリストを呼び出す

パンくずリストを呼び出すコード

手順①と②が完了したら、パンくずリストを呼び出したい場所に、以下の記述を書き込みます。

<?php custom_breadcrumb(); ?>

私の場合は投稿記事とカテゴリーのページに呼び出したかったので、「single.php(個別投稿)」と「category.php(カテゴリーテンプレート)」の2か所に書き込んでおきました。

あとは表示させたい場所を確認すれば……

カテゴリーのページに表示されたパンくずリスト

このとおりOKです!

パンくずリストのリッチリザルトテストの結果

パンくずリストがより専門的な「構造化データ」として登録できているかは、Googleのリッチリザルトテストのページで確認することができます。

有効なアイテムが検出されれば、リッチな地図のできあがり! 今回の作業は以上です。

今回のまとめ

・パンくずリストはユーザーと検索エンジンに対して必要
・実装はコピペ3発で完了、コードは長くても問題なし
・道しるべを設置してユーザーが帰れる「家」をつくろう!

私がはじめて「パンくずリスト」という名前を聞いたとき、見ていた記事の筆者が勝手に名づけてそうよんでいるのかと思ったものです。が、これには、きちんとした意味と由来があります。

その由来とは、グリム童話の「ヘンゼルとグレーテル」にあるのだそう。

兄のヘンゼルと妹のグレーテルが、森をさまよい、魔女が住むお菓子の家にたどりつくお話、といえば「ああ、あれね」となるでしょうか。

さて、話のなかで、ヘンゼルは森から家に帰れるよう、ボロボロにくずしたパンのクズを道しるべとして地面に置いていく、というエピソードがあります。

これこそが、パンくずリストの由来だそうです。

見ている記事からトップページまでの経路が把握できれば、ユーザーはどこから入ってきても現在地を把握できるようになり、そして、いつだってホームに帰ってこられる。

ホームページとは私たちの家です。パンくずリストを設置し、道しるべをつくってあげれば、お客さんは、いつでも家に帰ってこられるようにもなるのではないでしょうか?

もちろん、それは魔女が住むお菓子の家ではないので、捕って食おうなんてことをするものではありません。

ただ遊びに帰ってこれる家。それがホームページ、ブログってものでしょう。まあパンくずリストは、あったほうがいいということです。

関連記事&スポンサーリンク

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

目次
閉じる