
WordPressで動的に出力されるschema.org準拠のパンくずリストを作成する
サイト内にあるよく使われるパーツにはいろんなものがありますが、その中の一つに「パンくずリスト」があります。WordPressサイトの場合には、自動的に生成されるプラグインも用意されていますが、カスタマイズしたい場合などは逆に面倒だったりします。そこで今回は、ページに合わせて動的にリストが出力されるパンくずリストを、schema.orgの仕様に準拠した形で実装してみたいと思います。
ちなみに過去記事「WordPressの固定ページでシンプルなパンくずリストをプラグインなしで実装する」でも実装方法についてまとめていますが、今回はこちらのグレードアップ版で、投稿一覧ページや詳細ページなども対応しているものになります。
まずは、ベースとなるHTMLをテンプレート側に用意します。今回はol要素で作成し、schema.orgに準拠したものになるので、下記のような属性値を設定しています。こうすることで検索結果にも良い影響を与えることができますね。そして、2番目以降のリストは動的に出力される部分になるので、ここを別途コンポーネントとして読み込めるようにしておきます。
【テンプレート側のPHP】※一部抜粋
これでページに合わせて動的にリストが表示されるパンくずリストができました。汎用性のあるパーツとして使いまわすこともできますし、カスタマイズもしやすいのではないでしょうか。クライアントワークでもよく登場する場面があると思いますので、ぜひ試してみてください。
<ol itemscope itemtype="https://schema.org/BreadcrumbList"> <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <a href="<?php echo esc_url(home_url()); ?>" itemprop="item"> <span itemprop="name">Home</span> </a> <meta itemprop="position" content="1" /> </li> <?php get_template_part( 'breadcrumb-list' ); ?> </ol>続いて、動的に出力される部分の処理を記述していきます。まずは必要となる情報をそれぞれ取得し、変数に格納しておくようにしておきます。あとはWordPressに用意されている条件分岐タグ(過去記事「WordPressでよく使うテンプレートタグのまとめ【条件分岐タグ】」参考)を使って、ページごとに出力されるリストを切り分けていきます。 【breadcrumb-list.php】
<?php
$postId = $post->ID;
$parentPostArry = array_reverse(get_post_ancestors($post));
$postTypeObject = get_post_type_object(get_post_type());
$postTypeName = $postTypeObject->labels->name;
$taxonomySlug = get_query_var('taxonomy');
$termName = urldecode(get_query_var('term'));
if(is_front_page() || is_home()) {
// トップページ
return false;
} else if(is_page()) {
// 固定ページ
function is_subpage() {
global $post;
if ( is_page() && $post->post_parent ) {
return $post->post_parent;
} else {
return false;
}
}
if(is_subpage()) {
foreach($parentPostArry as $index => $parentsPostId) {
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_permalink($parentsPostId).'" itemprop="item"><span itemprop="name">'.get_the_title($parentsPostId).'</span></a>';
echo '<meta itemprop="position" content="'.($index + 2).'" /></li>';
$parentPages = $index + 1;
}
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_permalink($postId).'" itemprop="item"><span itemprop="name">'.get_the_title($postId).'</span></a>';
echo '<meta itemprop="position" content="'.($parentPages + 2).'" />';
} else {
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_the_permalink().'" itemprop="item"><span itemprop="name">'.single_post_title('',false).'</span></a>';
echo '<meta itemprop="position" content="2" /></li>';
}
} else if(is_post_type_archive()) {
// カスタム投稿一覧ページ
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_post_type_archive_link(get_post_type()).'" itemprop="item"><span itemprop="name">'.$postTypeName.'</span></a>';
echo '<meta itemprop="position" content="2" /></li>';
} else if(is_tax()) {
// カスタム分類一覧ページ
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_post_type_archive_link(get_post_type()).'" itemprop="item"><span itemprop="name">'.$postTypeName.'</span></a>';
echo '<meta itemprop="position" content="2" /></li>';
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_term_link($termName, $taxonomySlug).'" itemprop="item"><span itemprop="name">'.single_term_title('',false).'</span></a>';
echo '<meta itemprop="position" content="3" /></li>';
} else if(is_singular(get_post_type())) {
// カスタム投稿詳細ページ
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_post_type_archive_link(get_post_type()).'" itemprop="item"><span itemprop="name">'.$postTypeName.'</span></a>';
echo '<meta itemprop="position" content="2" /></li>';
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<a href="'.get_the_permalink().'" itemprop="item"><span itemprop="name">'.single_post_title('',false).'</span></a>';
echo '<meta itemprop="position" content="3" /></li>';
} else if(is_search()) {
// 検索結果ページ
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<span itemprop="name">キーワード検索結果</span><meta itemprop="position" content="2" /></li>';
} else if(is_404()) {
// 404ページ
echo '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
echo '<span itemprop="name">ページが見つかりません</span><meta itemprop="position" content="2" /></li>';
} else {
return false;
}
?>
上記では、トップページ以外のページにおいて、2つ目以降のリストが表示されるようになっており、固定ページでは親ページがあれば遡って全て表示されるようになっています。カスタム分類や詳細ページについては、前のリストに紐づく投稿一覧ページがリストに表示される仕組みになっています。ポイントとなるのは、固定ページなどで2つ以上の繰り返しが行われる際に、meta要素に順番を設定してあげる必要があるので、インデックス番号を取得し、そこから番号を当て振られるようにしておきます。上記では通常投稿のカテゴリ一覧とタグ一覧や投稿者別アーカイブ、日付別アーカイブには対応していないので、必要に応じてカスタマイズしてください。
また、パンくずリスト作成に必要となる情報を投稿データから取得できる関数をいくつか下記にまとめていますので合わせて参考にどうぞ。
| get_post_type_object( $post_type ) | 投稿タイプに関する情報を取得できます。引数には対象となる投稿タイプを指定します。 |
|---|---|
| get_query_var( 'taxonomy' ) | 引数に「taxonomy」と指定することで、一覧ページとして表示されているカスタム分類のスラッグを取得できます。 |
| get_query_var( 'term' ) | 引数に「term」と指定することで、一覧ページとして表示されているカスタム分類のタームのスラッグを取得できます。 |
| single_term_title( $prefix, $display ) | 個別ページで、紐づくタームの名前を取得できます。第一引数には名前の前後に入る文字を指定し、第二引数では出力表示をするかどうかを指定できます。 |
categories
- WordPress(61)
- JavaScript(49)
- Vue.js(48)
- CSS(46)
- jQuery(34)
- Nuxt.js(22)
- Sass(21)
- Gulp(17)
- webpack(16)
- PHP(14)
- HTML(14)
- GSAP(11)
- React(10)
- Vite(9)
- Pug(9)
- Laravel(8)
- Cordova(8)
- Linux(7)
- Next.js(6)
- Apache(5)
- Shopify(4)
- REST API(4)
- Node.js(4)
- Smarty(3)
- Git(3)
- JSON(3)
- その他プログラミング(3)
- Google Apps API(3)
- Bootstrap(3)
- 環境構築・システム(3)
- TypeScript(2)
- EJS(2)
- RMS(2)
- Docker(2)
- Instagram API(2)
- Excel VBA(2)
- SVG(1)
- Dart(1)
- ECカートASP(1)
- Markdown(1)
- AMP(1)
- Nginx(1)
- XML(1)
- shellscript(1)
- Ruby(1)
- MySQL(1)