1. HOME»
  2. プログラミング・Web»
  3. WordPress»
  4. 【WordPress】パンくずリストをプラグイン無しで自作する方法

【WordPress】パンくずリストをプラグイン無しで自作する方法


※追記(2018/2/12)
もっと高機能になるように、改良修正しました。


人生で3回ほど死にそうになったことがある@It_is_Rです。

WordPressのパンくずリストを作るにはプラグインを使えば簡単ですが、あまりプラグインばかりに頼りたくないので、自作してみました。
今回はその方法を書いていきたいと思います。

目次
  1. パンくずリストとは
  2. どのようなパンくずリストを作るか
  3. パンくずリストを作成する方法
  4. 完成
  5. まとめ

パンくずリストとは

まずパンくずリストを知らない方の為に、パンくずリストとはなんなのかを軽く説明したいと思います。

パンくずリストは、ユーザーが今開いているページが一体どこなのかを表示してくれるものです。
例えばブログの記事を開いている場合、

home > カテゴリー > 記事タイトル

といったふうに、ヘッダーの下辺りに表示されることが多いです。

どのようなパンくずリストを作るか

まず、どのようなパンくずリストを作りたいか考えてみます。

  • トップページにはパンくずリストは必要ない
  • カテゴリーページには、「HOME > (カテゴリー名)」と表示
  • 月別アーカイブページには「HOME > (日時)」と表示
  • タグページには「HOME > (タグ名)」と表示
  • 投稿記事ページには「HOME > (カテゴリー名) > (記事タイトル)」と表示
  • 固定ページには「HOME > (固定ページタイトル)」と表示
  • 添付ファイルページには「HOME > (記事タイトル) > (ファイルの名前)」と表示
  • 検索ページには「HOME > 検索 : (検索ワード)」と表示
  • 404ページには「HOME > ページが見つかりません」と表示

ざっと思いつくものをあげてみました。
こんな感じで作っていきましょう。

パンくずリストを作成する方法

では、パンくずリストを作成してみましょう。
パンくずリストを呼び出すmytheme_breadcrumb()という関数をfunctions.phpに作り、それぞれのページからそれを読み込むという方法にします。

もしもトップページにパンくずリストを表示させたくない場合、if ( !is_front_page() && !is_home() ) を使います。

functions.php

function mytheme_breadcrumb() {
	if ( !is_front_page() && !is_home() ) :

	endif;
}

このようにしておくと、トップページからパンくずリストを呼んでしまった場合に表示されなくなるので便利です。
が、トップページから呼び出さなければいいという考えもあると思います。

この条件分岐を使うか使わないかは自由です。

区切り文字の指定とトップページへのリンク

次に、それぞれのページを区切る文字を指定し、トップページへのリンクも作成します。
$sepには、区切り文字に使用したい文字を代入します。

functions.php

$sep = '>';
echo '<a href="'.get_bloginfo('url').'" >HOME</a>';
echo $sep;

この状態で実行すると、以下のようになります。

HOME>

ちょっとパンくずリストっぽくなってきましたね。

投稿記事ページ、固定ページ、添付ファイルページ

投稿記事ページ、固定ページ、添付ファイルページのタイトルは、どれもthe_title();で取得出力できるので、まとめて書いてしまいましょう。

全てのカテゴリーを取得してみる

まず、全てのカテゴリーを取得してみましょう。ちょっとパンくずリストっぽくなります。

functions.php

if( is_singular() ) {
	if ( is_single() ) {
		the_category(', ');
		echo $sep;
	}
	the_title();
}

1行目のis_singular()は、閲覧者が開いているページが投稿記事ページ、固定ページ、添付ファイルページだった場合の条件分岐に使えます。

2〜5行目で、閲覧者が見ているページが投稿記事ページだった場合に、カテゴリー名と区切り文字を表示します。

6行目で、閲覧者が見ているページタイトルを表示します。

投稿記事ページの場合のみ、カテゴリー名を表示します。
固定ページの場合はタイトルのみです。

先ほど、トップページへのリンクと区切り文字は作成したので、それと合わせて実行すると以下のようになります。
(投稿記事ページで実行した場合)

HOME>カテゴリー名,カテゴリー名,カテゴリー名...>記事タイトル

これで良ければ一番簡単な方法かもしれません。ただ、この方法では、記事が属するカテゴリーが全て表示されてしまうのでかっこ悪いです。

get_category_parents を使う方法

この方法ならば、親子関係もしっかりと表示されます。

functions.php

if( is_singular() ) {
	if ( is_single() ) {
		$cat = get_the_category();
		echo get_category_parents($cat[0], true, $sep);
	}
	the_title();
}

(投稿記事ページで実行した場合)

HOME>親カテゴリー名>子カテゴリー名>記事タイトル

では、生成されるコードを見てみましょう。

<a href="http://url.com" >HOME</a>
>
<a href="http://url.com/category/親カテゴリー/">親カテゴリー名</a>
>
<a href="http://url.com/category/親カテゴリー/子カテゴリー/">子カテゴリー名</a>
>
記事タイトル

一つ一つのカテゴリーが、aタグに入っている感じです。
ここで思うのは、このaタグをliタグに入れたい場合はどうすればいいんだということでしょう。

PHPで、文字を置き換えたりして実現する方法もあると思いますが、あまり気持ちのいい方法ではないですね。

get_the_category を使う方法

get_category_parents()は簡単にパンくずリストが作れて便利なのですが、思うようなタグが生成されないので、不便な部分もあります。
そこで、get_the_category()を使う方法を紹介します。

functions.php

function mytheme_breadcrumb() {
	$sep = '>';
	echo '<li><a href="'.get_bloginfo('url').'" >HOME</a></li>';
	echo $sep;
	if( is_singular() ) {
		if ( is_single() ) {
			$cats = get_the_category();
			if( isset($cats[0]->term_id) ) $cat_id = $cats[0]->term_id;
			$cat_list = array();
			while ($cat_id != 0){
				$cat = get_category( $cat_id );
				$cat_link = get_category_link( $cat_id );
				array_unshift( $cat_list, '<a href="'.$cat_link.'">'.$cat->name.'</a>' );
				$cat_id = $cat->parent;
			}
			foreach($cat_list as $value){
				echo '<li>'.$value.'</li>';
				echo $sep;
			}
		}
		the_title('<li>', '</li>');
	}
}

7行目 : get_the_category()を使っています。これで投稿記事ページのカテゴリーを取得します。
8行目 : isset()を使い、$cats[0]->term_idがNULLでなかった場合、$cat_idに$cats[0]->term_idを代入します。
9行目 : ループに入る前に、配列を使う宣言をしておきます。
10行目 : $cat_idが0でない時、つまりカテゴリーが存在する場合はループします。
11行目 : get_category( $cat_id )で、カテゴリーIDから、カテゴリーの情報を取得します。
12行目 : get_category_link( $cat_id )で、カテゴリーIDから、カテゴリーページへのリンクを取得します。
13行目 : array_unshift()で、ループ前に宣言しておいた配列の一番前に、カテゴリーページへのリンクを入れていきます。
14行目 : 親カテゴリーIDを、$cat_idに代入します。こうすることで、ループごとに順番に親カテゴリーに登っていくことができます。
16〜19行目 : 配列に入れたリンクを、liタグ付きで出力します。

生成されたコード

<li><a href="http://url.local" >HOME</a></li>
>
<li><a href="http://url.local/category/親カテゴリー/">プログラミング・Web</a></li>
>
<li><a href="http://url.local/category/親カテゴリー/子カテゴリー/">WordPress</a></li>
>
<li>記事タイトル</li>

liタグ付きで生成してくれました。この場合、olやulタグから呼び出す必要があるので注意しましょう。

カテゴリーページや、月別アーカイブページ、タグページ

さて、カテゴリーページ、日時のページ、タグページのパンくずリストを作っていきます。

しかし、これらのページを一つずつ作っていく必要はありません。これらは全部アーカイブです。

functions.php

if ( is_archive() ) the_archive_title();

これで、現在のカテゴリー名、月別アーカイブ名、タグ名が取得できます。簡単ですね。

ただ、カテゴリーページに関しては、現在のカテゴリー名に加えて、その階層を表示させる必要があります。
つまり、現在のカテゴリーよりも上のカテゴリーを表示しなくてはなりません。

そこで、get_queried_object()を使います。

get_queried_object を使う方法

get_queried_object()を使い、現在のカテゴリーの情報を取得した後、その親のIDを取得します。

方法としては、現在のカテゴリーからの情報を取得するか、現在の親カテゴリーからの情報を取得するかの違いで、投稿記事ページで作ったものとほぼ同じです。

functions.php

function mytheme_breadcrumb() {
	$sep = '>';
	echo '<li><a href="'.get_bloginfo('url').'" >HOME</a></li>';
	echo $sep;
	if ( is_category() ) {
		$cats = get_queried_object();
		$cat_id = $cats->parent;
		$cat_list = array();
		while ($cat_id != 0){
			$cat = get_category( $cat_id );
			$cat_link = get_category_link( $cat_id );
			array_unshift( $cat_list, '<a href="'.$cat_link.'">'.$cat->name.'</a>' );
			$cat_id = $cat->parent;
		}
		foreach($cat_list as $value){
			echo '<li>'.$value.'</li>';
			echo $sep;
		}
	}
	if ( is_archive() ) the_archive_title('<li>', '</li>');
}

検索ページ

検索ページのパンくずリストは、次のように入力します。

functions.php

if( is_search() ) echo '検索 : '.get_search_query();

これで検索したワードが出力されます。

404ページ

ページが見つからなかった場合の表示です。

functions.php

if( is_404() ) echo 'ページが見つかりません';

完成

とりあえずこれで完成ですので、全体をまとめます。
今回紹介したやり方をまとめる場合、一応elseでif文を繋いでおくことにします。

functions.php

function mytheme_breadcrumb() {
	//HOME>と表示
	$sep = '>';
	echo '<li><a href="'.get_bloginfo('url').'" >HOME</a></li>';
	echo $sep;

	//投稿記事ページとカテゴリーページでの、カテゴリーの階層を表示
	$cats = '';
	$cat_id = '';
	if ( is_single() ) {
		$cats = get_the_category();
		if( isset($cats[0]->term_id) ) $cat_id = $cats[0]->term_id;
	}
	else if ( is_category() ) {
		$cats = get_queried_object();
		$cat_id = $cats->parent;
	}
	$cat_list = array();
	while ($cat_id != 0){
		$cat = get_category( $cat_id );
		$cat_link = get_category_link( $cat_id );
		array_unshift( $cat_list, '<a href="'.$cat_link.'">'.$cat->name.'</a>' );
		$cat_id = $cat->parent;
	}
	foreach($cat_list as $value){
		echo '<li>'.$value.'</li>';
		echo $sep;
	}

	//現在のページ名を表示
	if ( is_singular() ) {
		if ( is_attachment() ) {
			previous_post_link( '<li>%link</li>' );
			echo $sep;
		}
		the_title( '<li>', '</li>' );
	}
	else if( is_archive() ) the_archive_title( '<li>', '</li>' );
	else if( is_search() ) echo '<li>検索 : '.get_search_query().'</li>';
	else if( is_404() ) echo '<li>ページが見つかりません</li>';
}

また、パンくずリストを呼び出す命令は以下の通り。

<?php mytheme_breadcrumb(); ?>

あとはお好みでスタイルを適用して、かっこいいパンくずリストを作ってください。

まとめ

いかがだったでしょうか。

今回はパンくずリストを作ってみました。もしバグ等あればご報告お願いいたします。
今現在、私はパンくずリストの表示にプラグインを使っていますが、そのうちに自作のものに切り替えるつもりでいます。

以上、プラグイン無しでパンくずリストを自作する方法でした。

オリジナルゲーム.com