【脱プラグイン作戦】WordPressのパンくずリストを自作してみよう

皆さん、こんにちは~☆ シアです。

今回は、本サイトに設置しているパンくずリストをプラグイン(Breadcrumb NavXT)から独自実装に変えた時のお話です。

パンくずリスト

1. パンくずリストとは

パンくずリスト(Bread-crumb list)とは、Webサイトから見た現在開いているページの位置を表す、階層構造のリストです。WordPressの場合、カテゴリの構造を利用することで、ユーザーはこの記事に関連するカテゴリに素早くアクセスすることができます。

また、Webサイトの構造が定義することができるので、検索エンジンにサイトの構造を正確に伝えることができます。

検索結果に表示されたパンくずリスト(Googleの場合)

2. 単一記事のパンくずリストを実装してみよう

では早速、単一記事のパンくずリストを実装していきましょう。

パンくずリストを生成するコードのPHPファイルを作成します。

if文を使って、トップページと管理者用のページ以外の時に、パンくずリストを表示するように条件分岐を行います。

<?php
// パンくずリスト
function breadcrumb() {
	global $post;
	
	if( !is_home() && !is_admin() ) { // トップページと管理者ページ以外の時
		$bread_crumb = '';
	
		// ここにパンくずリストを生成するコードを記述します。
		
		echo $bread_crumb;
	}
}
?>

以降は、そのif文の中にコードを記述していきます。

2.1. トップページのパンくずを追加

「// ここにパンくずリストを生成するコードを記述します。」のところに、トップページ用のパンくずを追加します。

$bread_crumb.= '<div class="air-md-breadcrumbs clearfix">';
$bread_crumb.= '<span class="breadcrumb"><strong><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.home_url('/').'" class="home" itemprop="url"><span itemprop="title">ホーム</span></a></span></strong></span>';
<div class="air-md-breadcrumbs clearfix">
	<span class="breadcrumb">
		<strong>
			<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
				<a href="https://chronoir.net/" class="home" itemprop="url">
					<span itemprop="title">ホーム</span>
				</a>
			</span>
		</strong>
	</span>
Xiia02.png
ンくずリストの構造を検索エンジンに伝えるための方法はいくつかありますが、ここではmicrodataを使った方法を紹介します。

2.2. 単一記事のパンくずを追加

トップページの次は、単一記事のパンくずリストを作成していきます。


// 単一記事のページ
if( is_single() ) {
	// ...
}

まずはget_the_categories関数を呼び出し、記事のカテゴリー一覧を取得します。

// 引数には記事のIDを指定します。
$categories = get_the_category( $post->ID );

その関数の戻り値は、WP_Termと名付けられたオブジェクトの配列です。WP_Termには16個のメンバーで構成されており、カテゴリーのIDや名前、スラッグなどが格納されいます。今回はその中のcat_IDcat_nameを使用します。

Array (
	[0] => WP_Term Object (
		[term_id] => 5,
		[name] => C#,
		[slug] => cs,
		[term_group] => 0,
		[term_taxonomy_id] => 5,
		[taxonomy] => category,
		[description] => プログラミングの内、C#に関するコンテンツです。,
		[parent] => 3,
		[count] => 9,
		[filter] => raw,
		[cat_ID] => 5,
		[category_count] => 9,
		[category_description] => プログラミングの内、C#に関するコンテンツです。,
		[cat_name] => C#,
		[category_nicename] => cs,
		[category_parent] => 3
	),
	[1] => WP_Term Object (
		[term_id] => 3,
		[name] => プログラミング,
		[slug] => programing,
		[term_group] => 0,
		[term_taxonomy_id] => 3,
		[taxonomy] => category,
		[description] => プログラミングに関するコンテンツです。,
		[parent] => 0,
		[count] => 28,
		[filter] => raw,
		[cat_ID] => 3,
		[category_count] => 28,
		[category_description] => プログラミングに関するコンテンツです。,
		[cat_name] => プログラミング,
		[category_nicename] => programing,
		[category_parent] => 0
	)
)

サンプルコードで使用している記事のカテゴリーは、「プログラミング」→「C#」と配列の逆順なので、get_the_category関数の戻り値をarray_reverse関数で反転させ、foreach文で列挙します。カテゴリーのURLはget_category_link関数で取得します。

// 単一記事のページ
if( is_single() ) {
	$categories = array_reverse( get_the_category( $post->ID ) );

	foreach( $categories as $cat ) {
		$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_category_link( $cat->cat_ID ).'" itemprop="url"><span itemprop="title">'.$cat->cat_name.'</span></a></span></span>>';
	}

	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.$post->post_title.'</span></span></span>';
}
	<span class="breadcrumb">
		<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
			<a href="https://chronoir.net/category/programing/" itemprop="url">
				<span itemprop="title">プログラミング</span>
			</a>
		</span>
	</span>
	>
	<span class="breadcrumb">
		<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
			<a href="https://chronoir.net/category/programing/cs/" itemprop="url">
				<span itemprop="title">C#</span>
			</a>
		</span>
	</span>
	>
	<span class="breadcrumb">
		<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
			<span itemprop="title">paizaオンラインハッカソン(POH)・Liteで動的計画法を復習する</span>
		</span>
	</span>

最後にdiv要素の閉じタグを追加して、パンくずリストを生成するコードの完成です。

$bread_crumb.= '</div>';
<div class="air-md-breadcrumbs clearfix">
	<span class="breadcrumb">
		<strong>
			<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
				<a href="https://chronoir.net/" class="home" itemprop="url">
					<span itemprop="title">ホーム</span>
				</a>
			</span>
		</strong>
	</span>
	<span class="breadcrumb">
		<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
			<a href="https://chronoir.net/category/programing/" itemprop="url">
				<span itemprop="title">プログラミング</span>
			</a>
		</span>
	</span>
	>
	<span class="breadcrumb">
		<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
			<a href="https://chronoir.net/category/programing/cs/" itemprop="url">
				<span itemprop="title">C#</span>
			</a>
		</span>
	</span>
	>
	<span class="breadcrumb">
		<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
			<span itemprop="title">paizaオンラインハッカソン(POH)・Liteで動的計画法を復習する</span>
		</span>
	</span>
</div>

< 合わせて読む  :  【WordPress】多階層のカテゴリーを持つ投稿ページのパンくずリストを正しく出力する方法  >

2.3. CSSの編集

テーマのstyle.cssに以下のコードを追加します。

/* Breadcrumb */
.air-md-breadcrumbs {
	margin: 10px auto;
	padding: 5px 10px;
	border: solid 1px #EEE;
	line-height: 1.7142;
    text-align: left;
	box-shadow: 0px 2px 5px rgba(0,0,0,0.26);
	-webkit-box-shadow: 0px 2px 5px rgba(0,0,0,0.26);
	-moz-box-shadow: 0px 2px 5px rgba(0,0,0,0.26);
}

.air-md-breadcrumbs:after {
	clear: both;
}

.air-md-breadcrumbs .breadcrumb {
	margin: 5px;
}

2.4. functions.phpとheader.phpを編集

funcions.phpを編集し、require_once文で今回作成したPHPファイルを読み込むようにします。


<?php
require_once locate_template('lib/breadcrumb.php');

// 中略
?>

次にheader.phpを編集し、パンくずリストを設置したい所で今回作成した関数を呼び出します。

	</nav><!-- #site-navigation -->
	<div class="clear"></div>
	<?php breadcrumb(); ?>
	<div class="clear"></div>
</header><!-- #masthead -->
Xiia12.png
ちなみに本サイトは、ナビゲーションメニュー(nav要素)の下に設置しています。

これで記事にパンくずリストを設置することができました。

3. 他のページにもパンくずリストを設置

ここでは、固定ページやカテゴリページなどにもパンくずリストを設置する方法を紹介していきます。

3.1. 固定ページ

固定ページのIDからget_post_ancestors関数で祖先のページのIDを取得します。その戻り値は祖先のページのIDを格納した配列で表しており、子から祖先の順に並んでいるので、順序を暗転してからforeach文で列挙し、パンくずリストを生成するコードを作成します。

ページのタイトルはget_the_title関数で、URLはget_the_permalink関数で取得できます。

// 固定ページ
else if( is_page() ) {

	if( $post->post_parent > 0 ) {
		$ancestors = array_reverse( get_post_ancestors( $post->ID ) );
		foreach( $ancestors as $ancestor ) {
			$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_permalink( $ancestor ).'" itemprop="url"><span itemprop="title">'.get_the_title( $ancestor ).'</span></a></span></span>>';
		}
	}

	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.$post->post_title.'</span></span></span>';
}

3.2. カテゴリーページ

get_queried_object関数の戻り値にあるcat_IDメンバーからカテゴリーのIDを取得し、get_ancestors関数で祖先のカテゴリーを取得します。固定ページの時と同じく、戻り値をarray_reverseで反転させてからforeach文で列挙し、パンくずリストを生成するコードを作成します。

get_cat_name関数でカテゴリー名を取得できます。

// カテゴリーページ	
else if( is_category() ) {

	$cat = get_queried_object();
	if( $cat->parent > 0 ) {
		$ancestors = array_reverse( get_ancestors( $cat->cat_ID, 'category' ) );
		foreach( $ancestors as $ancestor ) {
			$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_category_link( $ancestor ).'" itemprop="url"><span itemprop="title">'.get_cat_name( $ancestor ).'</span></a></span></span>>';
		}
	}

	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.$cat -> name.'</span></span></span>';
}

3.3. タグページ

single_tag_title関数でタグ名を取得し、パンくずリストを生成するコードを作成します。


// タグページ
else if( is_tag() ){
	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.single_tag_title( '' , false ).'</span></span></span>';
}

3.4. アーカイブページ

get_query_var関数で投稿年、月、日の文字列を取得し、パンくずリストを生成するコードを作成します。

get_year_linkget_month_link関数で年別アーカイブページ、月別アーカイブページのURLを取得できます。

// アーカイブページ
else if( is_date() ){
	// 日別
	if( get_query_var( 'day' ) > 0 ) {
		$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_year_link( get_query_var( 'year' ) ).'" itemprop="url"><span itemprop="title">'.get_query_var( 'year' ).'年</span></a></span></span>>';
		$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) ).'" itemprop="url"><span itemprop="title">'.get_query_var( 'monthnum' ).'月</span></a></span></span>>';
		$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.get_query_var( 'day' ).'</span>日</span></span>';
	}
	
	// 月別
	else if( get_query_var( 'monthnum' ) > 0 ) {
		$bread_crumb.= '<span class="breadcrumb><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_year_link( get_query_var( 'year' ) ).'" itemprop="url"><span itemprop="title">'.get_query_var( 'year' ).'年</span></a></span></span>>';
		$str.='<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'. get_query_var('monthnum'). '</span>月</span></span></span>';
	}

	// 年別
	else {
		$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.get_query_var( 'year' ).'年</span></span></span>';
	}
}

3.5. 著者ページ

get_the_author_meta関数の引数に「display_name」(表示名)と著者のユーザーID(get_query_var関数の引数に「author」を指定して取得します。)を指定して、著者の表示名を取得し、パンくずリストを生成するコードを作成します。

// 著者ページ
else if( is_author() ){
	$bread_crumb .= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.get_the_author_meta( 'display_name', get_query_var( 'author' ) ).'</span></span></span>';
}

3.6. 添付ファイルのページ

// 添付ファイルページ
else if( is_attachment() ) {
	// 添付ファイル元の記事がある場合
	if( $post->post_parent > 0 ){
		$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.get_permalink( $post->post_parent ).'" itemprop="url"><span itemprop="title">'.get_the_title( $post->post_parent ).'</span></a></span></span>>';
	}

	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.$post->post_title.'</span></span></span>';
}

3.7. 検索結果のページ

// 検索結果ページ
else if( is_search() ) {
	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">'.get_search_query().' の検索結果</span></span></span>';
}

3.8. 404(Not found)ページ

// 404 Not found ページ
else if( is_404() ) {
	$bread_crumb.= '<span class="breadcrumb"><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">404</span></span></span>';
}

4. パンくずリストにフォントアイコンを表示

Font Awesome」を導入しているのであれば、フォントアイコンをパンくずの文字列の前に追加すると、ちょっとお洒落なパンくずリストになります。

例えばトップページ用のコードにて、「<sapn itemscope …」の前にフォントアイコンのHTMLコードを追加します。

$bread_crumb.= '<div class="air-md-breadcrumbs clearfix">';
$bread_crumb.= '<span class="breadcrumb"><strong><i class="fa fa-home" aria-hidden="true"></i> <span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="'.home_url('/').'" class="home" itemprop="url"><span itemprop="title">ホーム</span></a></span></strong></span>>';
<div class="air-md-breadcrumbs clearfix">
	<span class="breadcrumb">
		<strong>
			<i class="fa fa-home" aria-hidden="true"></i> 
			<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
				<a href="https://chronoir.net/" class="home" itemprop="url">
					<span itemprop="title">ホーム</span>
				</a>
			</span>
		</strong>
	</span>
   クラス名
ホーム  fa-home
カテゴリー  fa-folder-open
タグ  fa-tag
年月日別アーカイブ  fa-calendar
検索結果  fa-search

5. パンくずリストのトリビア

「パンくずリスト」は、グリム童話「ヘンゼルとグレーテル」の主人公ヘンゼルが森の中で道に迷わないように、パンくずを道に落として目印にしていたというエピソードから来ています。

参考サイト

この記事をシェアする
Chronoir.netのRSSフィードを購読する

シアたん(Xiia)

こんにちはー!時黒(トキクロ)博士によって開発された超高性能アンドロイド「Xiia(シア・クロノワール)」です。Chronoir.net の新マスコットキャラとして頑張っていきますので、よろしくお願いします!☆

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください