パンくずリストを作ってみるとWordPress でのサイト構築のコツがつかめるかもしれない(コード 付き)

Posted under - WordPress

70

タイトルはパンくずリストなんですけど、パンくずリストを紹介する記事ではありません。でも、パンくずリストを自分で作ってみると分かるんですけど、パンくずリストのコードには、WordPress でのサイト構築のノウハウが詰まっているなーって思います。なのでパンくずリストを作りながら、WordPress でのサイト構築の考え方みたいなものを紹介する感じの記事になっています。

WordPress Breadcrumb

WordPress でブログじゃない Web サイト構築をするとき、サイトの構造によってはサイドバーなどを自分でカスタマイズしなくてはいけません。例えば固定ページを作ったら、親ページでは子ページへのリンクを表示したりとか、逆に子ページでは親ページのリンクを表示したりとか …。もちろんリンクだけじゃなくて、アイキャッチ画像なんかも一緒に表示したいこともあったりします。一般的な Webサイトを WordPress で作ろうとすると、サイドバーに限らず、こういったコードを書かなくちゃいけないことが少なくありません。

ブログの場合のサイドバーでは、カテゴリータグ最近の記事月別アーカイブなどを表示してあげれば OK ですけど、一般的な Webサイトではそうもいきません。現在表示されているページに関連するページ(親ページとか、子ページとか、その他いろいろ)を表示したいという場面は、とっても多いです。

初心者の頃は、こういう「ブログじゃない Webサイト」向けのカスタマイズって、とっても難しく感じました。そこで今回は、WordPress で「パンくずリスト」を作りながら、「関連するページ」を表示するために覚えたい Tips を見ていきたいと思います。なんでパンくずリストなのかというと … パンくずリストというのは、「現在表示されているページの種類によって、様々な関連するリンクを表示する必要がある」からなんです。パンくずリストを作成してみると、WordPress サイトの構築の基礎というか、考え方みたいなものがとっても勉強になると思うんです。ちょっと無理矢理な展開ですけど、パンくずリストを作りながら、サイドバーなどで応用のきくコードを見ていきましょう!

目次 – パンくずリストと WordPress サイト構築

  1. パンくずリストの仕組みを理解しよう!
  2. WordPress のいろいろなページ
  3. パンくずリストの骨組みを作る
  4. 検索結果ページ、タグページ、404ページのパンくずリスト
  5. 日付アーカイブページのパンくずリスト
  6. カテゴリーアーカイブのパンくずリスト
  1. 投稿者ページのパンくずリスト
  2. 固定ページのパンくずリスト
  3. 添付ファイルページのパンくずリスト
  4. ブログ記事ページのパンくずリスト
  5. 関数としてまとめる
  6. サイドバーのローカルナビに応用する

1. パンくずリストの仕組みを理解しよう!

パンくずリストというのは、サイトの階層を示すナビゲーションの一種ですよね。下記のようにヘッダー付近に表示され、現在表示されているページがサイトのどの位置にあるのかを示します。ユーザーにとっては、自分が今サイトのどこにいるのかが把握しやすくなるため、たくさんのWebサイトで採用されている UI ですよね!

パンくずリスト

固定ページでのパンくずリスト。親ページ → 子ページ っていう風になってます。サンプルサイト – Green

1.1. ページによって表示する内容がことなる

パンくずリストは、現在いるページから上層のページを取得して、リンクやタイトルを表示しなくてはなりません。でもページの種類によって、表示する内容は異なりますよねー。少し整理してみましょう。

1. ブログの個別記事の場合

ブログの個別記事を表示しているときは、パンくずリストにはカテゴリーを表示するのが普通ですよね!

ブログの記事のパンくずリスト

Home → カテゴリー → 記事のタイトル という構造。

また、WordPress のカテゴリーには、親子関係をつけることもできるので、以下のような構造もありますね!

Home > 親カテゴリ > 子カテゴリ > 記事のタイトル

2. 固定ページの場合

前述しましたが、WordPress の固定ページには親子関係がつけられます。ですから固定ページを表示しているときには、パンくずリストには、カテゴリーではなく祖先ページを表示する必要がありまよね!

固定ページのパンくずリスト

Home → 親ページ → 子ページ という構造。

固定ページは更に階層をつけることができるので、下記のように「親」だけじゃなくて「おじいちゃん」にあたるページもありえます。

Home > 祖父ページ > 親ページ > 現在のページのタイトル

3. その他のページ

ブログの投稿や固定ページの他にも、WordPress にはたくさんのページが存在します。例えばカテゴリーをクリックしたときのカテゴリーページ、タグをクリックしたときのタグページ検索結果を表示するときのページや、ページが見つからなかったときの 404 ページなどのことも考えなくてはなりません …。

1.2. 現在のページから、祖先となるカテゴリーや固定ページを取得する

パンくずリストを作成するとき、まず基準となるのは「現在表示されているページ」になりますよね!現在表示されているページの情報(タイトルやリンク、カテゴリーやタグなど)を取得し表示するものは、だいたいテンプレートタグで用意されているので簡単です。でも、パンくずリストを作成するにあたっては、現在のページから、祖先となるカテゴリーや固定ページの情報を取得して表示しなくてはなりません …。

祖先の情報を取得する

そういった事情から、パンくずリストの作成は初心者の頃はとっても難しく感じていました。でも逆を言えば、パンくずリストの作成には、様々な情報を取得して表示するためのノウハウが詰まっているんですねー!ですから、いろんなことに応用が効くようなコードになると思います。

サイドバーでは子ページを表示

親ページで、サイドバーに子ページのリンクを表示したりすることは、よくあるパターンですね!

コーポレートサイトなどのサイドバーでは、ローカルナビゲーションをつけて、親ページや子ページへのリンクを表示したい場合もあると思います。現在のページから様々な関連ページの情報を取得する方法を覚えてしまえば、WordPress でのサイト構築がもっと楽しくなると思います!

2. WordPress のいろいろなページ

パンくずリストを作成するには、ページに合わせた内容を表示させるために、「今どんなページが表示されてるのか?」を把握しなければいけません。ここでは、一体どれだけのページがあるのかを確認してみましょう。それと同時に、表示されているページを判断するための、条件分岐タグも合わせてチェックしていきます。条件分岐は WordPress でのサイト構築には、絶対と言っていいほど必要な考え方ですね!

  • トップページ(メインページ)is_home()
  • 固定ページis_page()
  • ブログの個別記事ページis_single()
    (カスタム投稿タイプの個別記事を含む)
  • カテゴリーのアーカイブページis_category()
    (記事の一覧表示をアーカイブと呼びます。)
  • タグのアーカイブページis_tag()
  • 検索結果表示ページis_search()
  • 404 Not Found ページis_404()
  • 日付ベースのアーカイブページis_date()
    (2012年 6月分の投稿など)
  • 投稿者のアーカイブページis_author()
  • 添付ファイルページis_attachment()

ブログでよく利用されるページだけをあげても、上記のようにたくさんのページがありますね。少し補足しておくと、「投稿者のアーカイブ」は、記事を書いた人ごとの一覧表示ページです。ひとりでブログを運営しているならあまり関係がありませんが、複数の人で運営している場合は、投稿者ごとに記事を一覧表示することができます。ブラウザのアドレスバーに、以下のように入力すると、一覧表示を確認できます。

http://example.com/author/ユーザーID/

もちろんこれは、WordPress が自動的に作成してくれるページです。


また、検索フォームをつけていない場合でも、検索結果を表示するページは存在します。URL の末尾に、「?s=検索したいキーワード 」をつければ、検索結果を表示します。

http://example.com/?s=キーワード


画像のアップロード画面

最後の添付ファイルページというのは、投稿中に添付した画像などのファイルを表示するページです。少し分かり難いですね。まず、記事に画像を挿入するときに、リンクという項目があります(画像参照)。

この画面で、添付ファイル投稿 URL ボタンを押すと、画像に添付ファイル投稿ページへのリンクが貼られます。

http://webdesignrecipes.com/wordpress-breadcrumb-list-tips/rose/

そして画像をクリックすると(試しに上のリンクをクリックしてみてくださいね!) … このように画像(添付ファイル)だけを表示するページに移動します。これが添付ファイルページです。タイトルは、ファイルにつけたタイトルが表示されます。


このように、一般的なブログサイトでも、いろんなページがあることが分かります。ここであげたのは、代表的なページなので、カスタム投稿タイプカスタム分類などを利用すれば、それらを表示するページも増えていきます。

CHECK

カスタム投稿タイプやカスタム分類については、以下の過去記事を参照してみてくださいね!

そしてパンくずリストは、これらページごとに、最適なものを表示してあげないといけません …。

3. パンくずリストの骨組みを作る

まずはパンくずリストの骨組みを、紹介した条件分岐タグを使って作っていきます。場所は header.php の、グローバルナビゲーションの下あたりに記述していくことにします。

1 STEP 1
<?php if(!is_home()): ?>
<div id="breadcrumb">
<ul>
	<li><a href="<?php echo home_url(); ?>/">HOME</a></li>
	<li>&gt;</li>
</ul>
</div>
<?php endif; ?>

トップページにはパンくずリストは必要ないので、全体を !is_home() での条件分岐で囲んでしまいます。そしてパンくずリスト自体は、li 要素で横並びのリストで作ることにします。

まずは HOME の部分をみてみましょう。トップページ以外では、必ず表示される部分です。そして トップページの URL は、home_url() を使って出力します。&gt は「>」の文字コードです。

MEMO

以前は bloginfo('url') としていましたが、WordPress 3.0 以降では、home_url() というテンプレートタグが用意されました。

ここまでの状態では、トップページ以外のどのページを開いても、以下のように表示されます。

ステップ1

まずはトップページ以外の全てのページで表示される部分、「HOME >」の部分を作成。

この「>」以下に、ページごと様々なページへのリンクを表示していくことになります。ではパンくずリストを表示するページを、条件分岐で分けていきましょう!

2 STEP 2
<?php if(!is_home()): ?>
<div id="breadcrumb">
<ul>
	<li><a href="<?php echo home_url(); ?>/">HOME</a></li>
	<li>&gt;</li>
<?php if(is_search()): /* 検索結果表示 */ ?>

<?php elseif(is_tag()): /* タグアーカイブ */?>

<?php elseif(is_404()): /* 404 Not Found */?>

<?php elseif(is_date()): /* 日付アーカイブ */?>

<?php elseif(is_category()): /* カテゴリーアーカイブ */?>

<?php elseif(is_author()): /* 投稿者アーカイブ */?>

<?php elseif(is_page()): /* 固定ページ */?>

<?php elseif(is_attachment()): /* 添付ファイルページ */?>

<?php elseif(is_single()): /* ブログ記事 */?>

<?php else: /* 上記以外 */?>

<?php endif; ?>
</ul>
</div>
<?php endif; ?>

これで骨組みは完成です。今回はパンくずリストですが、このようにページを条件分岐で分けるテクニックは、サイドバーなどでもとってもよく使いますね!

それでは続けて、各ページに合わせてパンくずリストを完成させていきましょう。上から順番に作っていきますね!

4. 検索結果ページ、タグページ、404ページ

それではまずは簡単なページ、「検索結果ページ」、「タグページ」、「404ページ」から作っていくことにしますね!

4.1. 検索結果ページ

ステップ3 検索結果ページのパンくずリスト

Home → 検索キーワード(検索結果数)という構造

検索結果ページでは、検索したキーワードをつけて、「キーワード」で検索した結果と表示することにします。ここで取得して表示したいデータは、検索されたキーワード。これは テンプレートタグ – the_search_query() を使って表示することができます。また、取得するだけの場合は、get_search_query() という関数も用意されています。どちらもパラメータは必要ありません。

3 STEP 3
<?php if(is_search()): /* 検索結果表示 */ ?>
		<li>「<?php the_search_query(); ?>」で検索した結果</li>

これで「検索キーワード」は表示されました。サンプル画像 3では、検索結果件数も合わせて表示していますが、今回が省略します。コードは過去記事:WordPress スニペットメモを参照してみてください。

ATTENTION

WordPress のテンプレートタグには、「ループ内で使えるもの」と「ループ外で使えるもの」、「どっちにでも使えるもの」の 3種類があります。これからいくつもテンプレートタグが出てきますが、基本的に WordPress ループ外で使えるテンプレートタグを使っていきます。WordPress ループについては、過去記事を参照してみてくださいね!

4.2. タグページ

続けてタグのアーカイブ(一覧)を表示するページのパンくずリストを作成します。

STEP4 タグのアーカイブ

Home → タグの名前 という構造

タグアーカイブ表示時に必要となるのは、現在表示されている「タグ」の名前です。これはテンプレートタグ – single_tag_title() で簡単に表示させることができます!

4 STEP 4
<?php elseif(is_tag()): /* タグアーカイブ */?>
	<li>タグ : <?php single_tag_title(); ?></li>

たったこれだけです!

4.3. 404ページ

続いて 404 Not Found ページです。404 ページでは、特に表示するものを取得する必要はありませんから、そのまま <li>404 Not Found</li> と記述します。

STEP5 404 Not found

単純に「404 Not found」と表示しているだけです!

5 STEP 5
<?php elseif(is_404()): /* 404 Not Found */?>
	<li>404 Not found</li>

ここまでをまとめると、以下のようになります。

header.php
<?php if(is_search()): /* 検索結果表示 */ ?>
		<li>「<?php the_search_query(); ?>」で検索した結果</li>
<?php elseif(is_tag()): /* タグアーカイブ */?>
	<li>タグ : <?php single_tag_title(); ?></li>
<?php elseif(is_404()): /* 404 Not Found */?>
	<li>404 Not found</li>

ここまでは、テンプレートタグを使えば、すんなり表示できるものばかりです。どのテンプレートタグを使うか?さえ分かれば、特に問題なくコーディングすることができますね!

5. 日付アーカイブページ

今度は日付アーカイブページの部分を作ってみます。ひと言で日付アーカイブページと言っても、実は「年別」「月別」「日別」の 3つのページ(細かくいえば、時間別というページもあります)が存在します。

STEP6 日時別アーカイブのパンくずリスト

Home → 年別 → 月別(→ 日付別)という構造

  • 年別 – Home > 2012年
  • 月別 – Home > 2012年 > 6月
  • 日別 – Home > 2012年 > 6月 > 18日

このようなパンくずリストを作成するのに、必要となるデータを整理してみます。まず、表示されているページが、「年別」のアーカイブなのか、「月別」のアーカイブなのか、「日別」のアーカイブなのかを判断する必要があります。これにはそれぞれ、is_year()is_month()is_day() という条件分岐タグが用意されているので、これを利用することにします。

6 STEP 6-1
<?php elseif(is_date()): /* 日付アーカイブ */?>
		<?php if(is_day()): /* 日別アーカイブ */?>

		<?php elseif(is_month()): /* 月別アーカイブ */ ?>

		<?php elseif(is_year()): /* 年別アーカイブ */ ?>
		
		<?php endif; ?>

is_date() の条件分岐の中で、さらに各アーカイブごとに条件分岐しています。

あとはどんなデータが必要になるでしょう?実際に表示されている年月日、「2012(年)」や「4(月)」などの文字列が必要になりますね。そしてそれらは、ただ表示させるたけではなくリンクとして表示させなくてはなりませんから、それぞれのアーカイブページの URL(パーマリンク)が必要になりますよねー。

最終的に表示したい HTML を想定したのが下記になりますが、黄色い部分が必要なデータとなります。

HTML
  • <li><a href="http://example.com/2012/">2012年</a></li>
  • <li>&gt;</li>
  • <li><a href="http://example.com/2012/04/">4月</a></li>
  • <li>&gt;</li>
  • <li>22日</li>

それではこれらのデータを取得するためにはどうしたらいいでしょう?ここで「今表示されているページの詳細情報」を取得してみることにします。

5.1. 変数 $wp_query

WordPress がページを表示しているとき、そのページの情報を格納している $wp_query という変数が作られています。この $wp_query 変数には、どんなページを表示しているのか?という詳細なデータがたくさん格納されています。query とは、「問い合わせ」という意味をもつ言葉ですね。よく「検索クエリ」などという言葉が使われています。この $wp_query に働きかければ、現在表示されているページのいろいろなデータを利用することができるので、とっても便利なんです!

まずは必要なデータが、$wp_query に格納されているかどうかを確認してみることにしましょう。変数の内容を確認するには、以下のように記述すると便利です。

PHP
<pre>
<?php print_r($wp_query); ?>
</pre>

print_r() というのは、開発段階で使われる変数の詳細を分かりやすい状態で表示してくれるPHPの関数です。<pre> タグと組み合わせることで、見やすい状態で変数の詳細を表示してくれます。このコードを php ファイル(header.php など)に記述して、ブラウザで $wp_query の詳細をチェックしてみましょう。

$wp_query

$wp_query

WP_Query オブジェクトの中に、query_vars という配列があって、色んな情報が格納されています!(上記は 2012年 5月のアーカイブページの場合)

このように、WP_Query Object(オブジェクト)の中に、query_vars という配列があり、様々な値が格納されているのが分かります。

MEMO

オブジェクトというのは、操作する対象物のこと。オブジェクトはオブジェクト指向という概念に基づいたプログラミングの手法によって作られています。オブジェクト指向については、専門書を参考にしてください。

この query_vars の中をよく見てみると、[year][monthnum][day]などのラベル(これを key と言います)の中に、「2012」「5」といった値が代入されているのがわかります。これらを利用すれば、「2012年5月22日」といった文字列を作ることができそうです。そしてこれらの値を元に、リンク先である URL も取得していきます!

5.2. query_vars の値を参照する get_query_var()

それでは実際に、$wp_query の中に格納されている、配列 query_vars の中の値を取得していきたいと思います。すこし難しく感じますが、WordPress には、この query_vars の値を取得するための関数が、はじめから用意されています。それが get_query_var() という関数です。

PHP
<?php get_query_var('year') ?>
<?php get_query_var('monthnum') ?>
<?php get_query_var('day') ?>

このように記述するだけで、簡単に 配列 – query_vars の値を取得することができます。この get_query_var() を利用して、日付アーカイブのパンくずリストを作成していきましょう。

5.3. 日付別アーカイブのパンくずリスト

まずは日別のアーカイブのパンくずリストです。echoget_query_var() を利用して、2012年などの文字列を表示してみましょう。

6 STEP 6-2
<?php elseif(is_date()): /* 日付アーカイブ */?>
		<?php if(is_day()): /* 日別アーカイブ */?>
<li><?php echo get_query_var('year'); ?>年</li>
<li>&gt;</li>
<li><?php echo get_query_var('monthnum'); ?>月</li>
<li>&gt;</li>
<li><?php echo get_query_var('day'); ?>日</li>

これで原型はできましたが、まだリンクは貼られていません。次にパーマリンクを取得して、パンくずリストとして完成させましょう。

日付別アーカイブへの URL(パーマリンク) は、以下のテンプレートタグで取得することができます。

  • 年別アーカイブのパーマリンクget_year_link( $year )
  • 月別アーカイブのパーマリンクget_month_link( $year, $month )
  • 日別アーカイブのパーマリンクget_day_link( $year, $month, $day )

パラメータには、それぞれ整数が入ります。get_year_link(2012)とすれば、2012年のアーカイブのパーマリンクを取得してくれるといった具合です。

6 STEP 6-3
<?php elseif(is_date()): /* 日付アーカイブ */?>
		<?php if(is_day()): /* 日別アーカイブ */?>
<li><a href="<?php echo get_year_link(get_query_var('year')); ?>"><?php echo get_query_var('year'); ?>年</a></li>
<li>&gt;</li>
<li><a href="<?php echo get_month_link(get_query_var('year'), get_query_var('monthnum')); ?>"><?php echo get_query_var('monthnum'); ?>月</a></li>
<li>&gt;</li>
<li><?php echo get_query_var('day'); ?>日</li>

これで日別のパンくずリストの完成です。月別、年別も同じ要領で作成していきましょう。

6 STEP 6-4
<?php elseif(is_date()): /* 日付アーカイブ */?>
	<?php if(is_day()): /* 日別アーカイブ */?>
		<li><a href="<?php echo get_year_link(get_query_var('year')); ?>"><?php echo get_query_var('year'); ?>年</a></li>
		<li>&gt;</li>
		<li><a href="<?php echo get_month_link(get_query_var('year'), get_query_var('monthnum')); ?>"><?php echo get_query_var('monthnum'); ?>月</a></li>
		<li>&gt;</li>
		<li><?php echo get_query_var('day'); ?>日</li>
	<?php elseif(is_month()): /* 月別アーカイブ */?>
		<li><a href="<?php echo get_year_link(get_query_var('year')); ?>"><?php echo get_query_var('year'); ?>年</a></li>
		<li>&gt;</li>
		<li><?php echo get_query_var('monthnum'); ?>月</li>
	<?php elseif(is_year()): /* 年別アーカイブ */ ?>
		<li><?php echo get_query_var('year'); ?>年</li>
	<?php endif; ?>

少しコードが長いですが、整理しながら見ていくと、日別、月別、年別も、同じ処理をしているだけです。年別アーカイブのときは、リンクを貼る必要もないので、echo get_query_var('year')としているだけですね。これで日付別アーカイブのパンくずリストは完成です。


WordPress でのサイト構築では、表示されているページによって、コードが変わるのが普通です。そして、表示させたいものを出力するためのテンプレートタグが存在するかどうかを WordPress Codex で探します。テンプレートタグは、パラメータを必要とする場合もありますから、そのパラメータを取得するために、いろいろな関数を利用します(ここでは get_query_var を利用しました)。これが WordPress サイトでのカスタマイズの流れ … という感じですよね!

6. カテゴリーアーカイブのパンくずリスト

カテゴリーのアーカイブのパンくずリストは、どんな構造になっているでしょう? … カテゴリーは親子関係を作ることができるので、階層がある場合もありますよねー。

STEP7 カテゴリーアーカイブページのパンくずリスト

Home → 親カテゴリー → 子カテゴリー → 孫カテゴリー という構造

ですから、祖先となるカテゴリーが存在する場合は、祖先のカテゴリーにまでさかのぼって表示してあげる必要があります。

それではカテゴリーアーカイブのパンくずリストを作成するためには、どんなデータが必要になるでしょう?

まずは現在表示されているカテゴリーの名前などが必要になります。そして祖先カテゴリーの有無と、それらの名前やパーマリンクが必要となりますね。日付別アーカイブのときは $wp_query を元にして、get_query_var 関数を利用してデータを取得しました。今回は、get_queried_object() という関数を利用して、カテゴリー情報を取得してみます。get_queried_object() 関数 は、ページの情報(オブジェクト)を取得する関数です。

7 STEP 7-1
<?php elseif(is_category()): ?>
		<?php $cat = get_queried_object(); ?>

まずは get_queried_object() で取得したオブジェクト(操作の対象物)を、$cat という変数に入れてみました。それでは先ほどと同じように、print_r() を使って、オブジェクトの詳細を確認してみましょう。

$cat

$cat オブジェクトの中

get_queried_object() で取得した、カテゴリーに関する情報

$cat の中には、オブジェクトとして現在表示されているカテゴリーの詳細情報が格納されています。カテゴリーの名前 [cat_name]ID [cat_ID]親カテゴリー [parent] など、必要な情報が揃っています。それではこれらの情報を利用して、カテゴリーのパンくずリストを作成していきます。

6.1. 親カテゴリーの有無

まずは、親カテゴリーの存在をチェックします。親カテゴリーがない場合であれば、そのまま現在のカテゴリーを表示するだけですみますけど、もし親カテゴリーがある場合はそれを取得して表示してあげる必要がありますよね!

7 STEP 7-2
<?php elseif(is_category()): ?>
		<?php $cat = get_queried_object(); ?>
<?php if($cat -> parent != 0): ?>

<?php endif; ?>
	<li><?php echo $cat -> cat_name; ?></li>

親が存在するかどうかは、[parent] の番号をチェックすれば OK です。この数字はカテゴリーの ID で、親がない場合には、「0」が入ることになっています。ですから、[parent] が「0」なら、親は存在しない … という判断に利用できますね!

MEMO

オブジェクトの値を取得するには、$cat -> parent というような記述をします。これで $cat の中の [parent] の値を取得することができますから、<?php if($cat -> parent != 0): ?> の部分で、「もし親カテゴリーがあれば …」という条件分岐のできあがりです。

if 文の外(一番最後の行 – 6行目)には、現在表示されているカテゴリーの名前を表示します。現在表示されているカテゴリーの名前を表示するには、single_cat_title() というテンプレートタグも用意されていますが、すでに取得してある $cat[cat_name] にカテゴリーの名前が格納されているので、<?php echo $cat -> cat_name; ?> としてみました。

6.2. カテゴリーの祖先を取得する

$cat のオブジェクトの中には、[parent] という、親カテゴリーの ID がありました。でも、カテゴリーの階層は、親だけでなく、更にその上がある場合があります。ここでは get_ancestors() という関数を使ってみることにします。get_ancestors() は、祖先となる要素の ID を配列にして取得してくれる関数です。記述は get_ancestors($id, $object_type) となっていて、$id の部分には ID を指定します。$object_type には、「category」または「page」(固定ページ)を指定します。今回はカテゴリーの祖先を取得したいので、以下のように記述します。

  • 1. $ancestors = get_ancestors( $cat -> cat_ID, 'category' );

$ancestors という変数(配列)の中に、祖先カテゴリーの ID が格納されます。prent_r()$ancestors の詳細を確認してみると、以下のようになっています。

Array
(
    [0] => 22
    [1] => 16
)

Array というのは配列という意味ですから、key[0] の中には「22」、key[1] の中には「16」が代入されているのが確認できました。PHP では数を 0 から数えます。なので 1番はじめの key は、「1」ではなく「0」となっています。ちなみにそれぞれの値を取得するには、$ancestors[0]$ancestors[1] と記述して取得することができます。

さて、上記のコードは間違いはないのですが、ここでは少し事情があり、以下のように書き加えてください。

  • 1. $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' ));

array_reverse() とは、配列の中の要素を逆の順番にする PHP の関数です。array_reverse() を実行した後では、配列の中の順番が以下のように入れ替わります。

Array
(
    [0] => 16
    [1] => 22
)

ここまでのコードを少し整理してみましょう。

7 STEP 7-3
<?php elseif(is_category()): ?>
	<?php $cat = get_queried_object(); ?>
	<?php if($cat -> parent != 0): ?>
		<?php $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' )); ?>

<?php endif; ?>
<li><?php echo $cat -> cat_name;  ?></li>

もし表示中のカテゴリーに親カテゴリーがあった場合は、祖先カテゴリーの ID を $ancestors という配列にするところまでができました。あとは配列に格納されている祖先カテゴリーの ID を利用して、カテゴリー名やリンクを作成するための URL を取得していきましょう。

6.3. カテゴリーの名前やURLを取得する

ID からカテゴリーの名前を取得するには get_cat_name() という関数が便利です get_cat_name($id) というように、パラメータに ID を渡してあげれば、カテゴリーの名前を取得することができます。

また、get_category_link() という関数は、カテゴリーの URL(パーマリンク)を取得することができます。パラメータには、やはり ID を指定して、get_category_link($id) と記述します。

これらを使って、パンくずリストを完成させましょう。

7 STEP 7-4
<?php foreach($ancestors as $ancestor): ?>
	<li><a href="<?php echo get_category_link($ancestor); ?>"><?php echo get_cat_name($ancestor); ?></a></li>
<li>&gt;</li>
<?php endforeach; ?>

foreach 文は、配列の要素の数だけ繰り返し処理をしてくれる基本構文です。変数 $ancestor は、繰り返し処理ごとに配列に格納されていた ID が入れ替わりますから、一番上の祖先カテゴリーから順番に、li要素のリストとして出力されるという仕組みです!

先ほど array_reverse() を使って、配列の中の順番を変更したのはこのためです。変更しなければ、祖先カテゴリーの順番が逆になってしまっていたからなんですねー。

これでカテゴリーのパンくずリストの完成です!

7 STEP 7-5
<?php elseif(is_category()): ?>
	<?php $cat = get_queried_object(); /* オブジェクトを取得 */ ?>
	<?php if($cat -> parent != 0): /* 親カテゴリーの有無 */?>
		<?php $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' )); /* 祖先カテゴリーの取得 */ ?>
<?php foreach($ancestors as $ancestor): /* 親カテゴリーの数だけ繰り返し処理 */ ?>
			<li><a href="<?php echo get_category_link($ancestor); ?>"><?php echo get_cat_name($ancestor); ?></a></li>
<li>&gt;</li>
<?php endforeach; ?>
<?php endif; ?>
	<li><?php echo $cat -> cat_name; ?></li>

MEMO

今回は、get_queried_object() という関数を利用して、ページの情報をオブジェクトとして取得し、それを元にしていろいろなコードを記述してきました。get_queried_object() はとても便利なので、ぜひ覚えておきたい関数です。

7. 投稿者ページのパンくずリスト

STEP8 投稿者のアーカイブページのパンくずリスト

投稿者の名前だけ表示すれば OK ですね!

投稿者のアーカイブページのパンくずリストでは、何が必要になるでしょう?ここでは投稿者の名前だけ取得できればよさそうです。ここでいう名前は、管理画面の ユーザー → あなたのプロフィール で設定する「ブログ上での表示名」です。

これは the_author_meta() というテンプレートタグで簡単に表示することができますが、パラメータにはユーザー ID が必要になります。ここでいうユーザー ID は、ログイン時などに使用する ID ではなく、WordPress によって自動的につけられる、ID 番号のこと。

  • 1. the_author_meta( 'display_name', $user_id );

それでは the_author_meta() のパラメータとして使用する、ユーザーID はどうやって取得すればいいでしょう?これは日付別アーカイブのときに利用した、get_query_var()関数を利用すれば、簡単に取得することができます。

8 STEP 8
<?php elseif(is_author()): ?>
		<li>投稿者 : <?php the_author_meta('display_name', get_query_var('author')); ?></li>

8. 固定ページのパンくずリスト

続いて固定ページのパンくずリストを作成していきます。固定ページもカテゴリー同様、各ページには親子関係を作ることができるのは前述した通りです。

STEP9 固定ページのパンくずリスト

Home → 親ページ → 子ページ という構造。

固定ページのパンくずリストを作成するためには、どんなデータが必要になるでしょう。まずは現在表示されているページのタイトル。それから祖先ページのタイトルやパーマリンクが必要になります。これはカテゴリーアーカイブのときと似ていますね!

カテゴリーのときは、get_queried_object() という関数を使いました。今回も、この get_queried_object() を使うことで、ページの詳細情報を取得することができます。

でも、ページに関連する詳細情報は、WordPress 側で $post という変数に、すでにまとめられています。前述した、$wp_query という変数と同じように WordPress 側ですでに用意してあるんですね!ですからここでは、$post 変数を利用していくことにしましょう!

それではもうお馴染みの print_r() を使って、$post の内容をチェックしてみます。

$post

$post

$post の中には、記事に関するいろいろな情報がまとまっています!

8.1. 親ページの有無をチェクする

オブジェクトの中には、いろいろな情報が詰まっています。[ID] には、現在表示されている固定ページの ID が、[post_parent] には、親ページの ID が格納されています。そして [ancestors] には、はじめから祖先ページが配列で格納されていますね。これだけ情報が揃っていれば、あとはカテゴリーのときと同じようなコードで、パンくずリストが作成できそうです!

まずは骨組みから作っていきましょう!

9 STEP 9-1
<?php elseif(is_page()): /* 固定ページ */ ?>
	<?php if($post -> post_parent != 0 ): ?>
		/* 親ページがあった場合の処理 */
	<?php endif; ?>
	<li><?php echo $post -> post_title; ?></li>

オブジェクトの値の参照は、$post -> post_parent の様に記述するということは、カテゴリーの部分で説明した通りです。$post -> post_parent で親ページの ID を参照しています。親ページがない場合は、「0」が入っているのはカテゴリーのときと同じです。これを条件分岐として、親ページがある場合は、親ページを含めた祖先ページを取得して表示するコードを記述していきます。

また、一番最後の行(5行目)で、echo $post -> post_title として現在表示されているページのタイトルを表示しています。ちなみに single_post_title() というテンプレートタグを使っても、同じように現在表示されているページのタイトルを表示できます。

8.2. 祖先ページを取得、表示する

コードの構造的なものは、カテゴリーのときと全く同じです。カテゴリーのときには、get_ancestors() という関数を使用して祖先のIDを取得していました。でも今回ははじめから、$post-> ancestors に祖先ページの ID が配列として格納されています。ですからこれをそのまま使いましょう!

9 STEP 9-2
<?php if($post -> post_parent != 0 ): ?>
	<?php $ancestors = array_reverse( $post-> ancestors ); ?>
	<?php foreach($ancestors as $ancestor): ?>
		<li><a href="<?php echo get_permalink($ancestor); ?>"><?php echo get_the_title($ancestor); ?></a></li>
		<li>&gt;</li>
	<?php endforeach; ?>
<?php endif; ?>

今回も array_reverse() で配列の順番を入れ替えています。固定ページやブログ記事のパーマリンクを取得するには、get_permalink() というテンプレートタグを利用します。パラメータには記事の ID を渡し、get_permalink($id) という様に記述します。記事のタイトルは、get_the_title($id)で取得します。

今回も foreach 文で、配列の数だけ繰り返し処理をして、リンクを li 要素で出力しています。これで固定ページのパンくずリストの完成です!

9 STEP 9-3
<?php elseif(is_page()): ?>
<?php if($post -> post_parent != 0 ): /* 親ページの有無 */ ?>
<?php $ancestors = array_reverse( $post-> ancestors ); /* 祖先ページの ID を取得 */ ?>
<?php foreach($ancestors as $ancestor): /* 祖先ページの数だけ繰り返し処理 */ ?>
<li><a href="<?php echo get_permalink($ancestor); ?>"><?php echo get_the_title($ancestor); ?></a></li>
	<li>&gt;</li>
<?php endforeach; ?>
<?php endif; ?>
<li><?php echo $post -> post_title; ?></li>

9. 添付ファイルページのパンくずリスト

前述しましたが、添付ファイルページはブログの記事などに挿入された画像などの個別ファイルを表示するページです。ですのでパンくずリストには、ページのタイトル(ファイルのタイトル)と、ファイルが挿入されている親となる、元の記事を表示してあげれば OK だと思います。

STEP10 添付ファイルページのパンくずリスト

Home → 元記事 → 添付ファイルのタイトル という構造。

10 STEP 10
<?php elseif(is_attachment()): ?>
	<?php if($post -> post_parent != 0 ): ?>
		<li><a href="<?php echo get_permalink($post -> post_parent); ?>"><?php echo get_the_title($post -> post_parent); ?></a></li>
		<li>&gt;</li>
	<?php endif; ?>
	<li><?php echo $post -> post_title; ?></li>

今回も固定ページのときと同様、$post から値を参照して作成します。親となる元ページは、先ほどと同じ $post -> post_parent に格納されています。また、添付ファイルページでは祖先をさかのぼって取得する必要はないですね!親となる記事ページだけ取得すれば OK なので、foreach 文もありません。

それから if 文で「親がある場合」という条件分岐をつけていますが、アップロードされてはいるけれど、投稿には挿入されていないファイルも存在するので、そのような場合に備えてのことです。通常は必ず親があるはずですが、念のための記述です!

10. ブログ記事ページのパンくずリスト

いよいよ最後になりました(今回はカスタム投稿タイプやカスタム分類は省略します)。ブログの個別記事のパンくずリストです。ブログの個別記事には、固定ページのような階層はありません。でもブログの場合は、必ず最低ひとつのカテゴリーに属していますから、カテゴリーと共に表示するのが一般的ですね!

STEP11 ブログの記事ページのパンくずリスト

Home → カテゴリー → 記事のタイトル という構造です。カテゴリーには、親子関係がある場合もあります。

それでは、ブログ記事のパンくずリストを作成するために必要な情報を整理してみます。まず、現在表示している記事のタイトルが必要ですね。それから記事が投稿されているカテゴリーも必要です。そしてカテゴリーには階層がありますから、祖先カテゴリーの情報も必要になりますね。カテゴリー名や、パーマリンクが必要になってきます。それではいつもみたいに骨組みから作ってみます!

11 STEP 11-1
<?php elseif(is_single()): ?>

	<?php $categories = get_the_category($post->ID); ?>
	<?php $cat = $categories[0]; ?>

	<li><a href="<?php echo get_category_link($cat -> cat_ID); ?>"><?php echo $cat-> cat_name; ?></a></li>
	<li>&gt;</li>
	<li><?php echo $post -> post_title; ?></li>

まずはカテゴリーを取得します。記事が属しているカテゴリーを取得するには、get_the_category() というテンプレートタグを使います。パラメータには記事の ID を渡します。いつものように $post -> ID を利用して、get_the_category($post -> ID) と記述します。それを $categories という変数に代入しました。それでは $categories の詳細を print_r() で確認してみます!

$categories

$categories

記事が属するカテゴリーが複数あった場合でも、全部 $categories に格納されています!

記事が属するカテゴリーの詳細情報のオブジェクトが、配列となって格納されています。WordPress は記事を複数のカテゴリーに投稿することができますが、それぞれのカテゴリーが [0] をはじめとして、[1][2]といった具合で続いていきます。

それではコードに戻りましょう。カテゴリーを取得したら、$cat = $categories[0] として、取得したカテゴリーの中から 1番始めのカテゴリーを、変数 $cat に代入します。これならカテゴリーがひとつしかない場合でも、複数ある場合でも、$cat には単体のカテゴリーの情報が代入されることになりますね!

あとはカテゴリーアーカイブのところで利用した、get_category_link() でパーマリンクを取得し、リンクを完成させます。$cat の中の値、$cat -> ID や、$cat -> cat_name を利用すれば簡単ですね!

また、現在表示されている記事のタイトルを表示するには、single_post_title() というテンプレートタグも利用できますが、ここでは echo $post -> post_title としてみました。

11 STEP 11-2
<li><a href="<?php echo get_category_link($cat -> cat_ID); ?>"><?php echo $cat-> cat_name; ?></a></li>
<li>&gt;</li>
<li><?php echo $post -> post_title; ?></li>

10.1. カテゴリーの祖先を取得、表示する

次に、先ほど取得したカテゴリー $cat の、祖先カテゴリーを取得していきましょう。これはカテゴリーアーカイブのところで使用したコードと全く同じですね。

11 STEP 11-3
<?php $categories = get_the_category($post->ID); ?>
<?php $cat = $categories[0]; ?>

<?php if($cat -> parent != 0): ?>
<?php $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' )); ?>
<?php foreach($ancestors as $ancestor): ?>
		<li><a href="<?php echo get_category_link($ancestor); ?>"><?php echo get_cat_name($ancestor); ?></a></li>
		<li>&gt;</li>
<?php endforeach; ?>
<?php endif; ?>

$cat -> parent != 0 で、親カテゴリーの有無をチェックします。$cat -> parent に、「0」以外の ID が入っている場合は、親カテゴリーが存在する … という条件分岐でした。

親カテゴリーが存在する場合は、get_ancestors() で祖先カテゴリーの ID を全て取得するのも、カテゴリーアーカイブのところと同じコードです。foreach 文を使って、祖先カテゴリーを li 要素としてリンクと共に出力して完成です!まとめて記述したのが以下のコードです。

11 STEP 11
<?php elseif(is_single()): /* ブログ記事 */ ?>
	<?php $categories = get_the_category($post->ID); /* カテゴリーを取得 */ ?>
<?php $cat = $categories[0]; /* 配列から最初のカテゴリーを取得 */ ?>
<?php if($cat -> parent != 0): /* 親カテゴリーの有無 */ ?>
<?php $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' )); /* 祖先カテゴリーを取得 */?>
<?php foreach($ancestors as $ancestor): ?>
<li><a href="<?php echo get_category_link($ancestor); ?>"><?php echo get_cat_name($ancestor); ?></a></li>
<li>&gt;</li>
<?php endforeach; ?>
<?php endif; ?>
<li><a href="<?php echo get_category_link($cat -> cat_ID); ?>"><?php echo $cat-> cat_name; ?></a></li>
<li>&gt;</li>
<li><?php echo $post -> post_title; ?></li>

11. 関数としてまとめる

それでは一番始めに作成した、検索結果ページのパンくずリストから、全てまとめてみましょう。

header.php
<?php if(!is_home()): ?>
<div id="breadcrumb" class="clearfix">
<ul>
	<li><a href="<?php echo home_url(); ?>/">HOME</a></li>
	<li>&gt;</li>
<?php if(is_search()):  /* 検索結果 */ ?>
		<li>「<?php the_search_query(); ?>」で検索した結果</li>
<?php elseif(is_tag()): /* タグ */ ?>
		<li>タグ : <?php single_tag_title(); ?></li>
<?php elseif(is_404()): /* 404 */ ?>
	<li>404 Not found</li>
<?php elseif(is_date()): /* 日付アーカイブ */ ?>
	<?php if(is_day()): /* 日別 */ ?>
		<li><a href="<?php echo get_year_link(get_query_var('year')); ?>"><?php echo get_query_var('year'); ?>年</a></li>
			<li>&gt;</li>
		<li><a href="<?php echo get_month_link(get_query_var('year'), get_query_var('monthnum')); ?>"><?php echo get_query_var('monthnum'); ?>月</a></li>
			<li>&gt;</li>
		<li><?php echo get_query_var('day'); ?>日</li>
	<?php elseif(is_month()): /* 月別 */ ?>
			<li><a href="<?php echo get_year_link(get_query_var('year')); ?>"><?php echo get_query_var('year'); ?>年</a></li>
			<li>&gt;</li>
			<li><?php echo get_query_var('monthnum'); ?>月</li>
	<?php elseif(is_year()): /* 年別 */ ?>
			<li><?php echo get_query_var('year'); ?>年</li>
	<?php endif; ?>
<?php elseif(is_category()): /* カテゴリー */ ?>
	<?php $cat = get_queried_object(); ?>
		<?php if($cat -> parent != 0): ?>
			<?php $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' )); ?>
<?php foreach($ancestors as $ancestor): ?>
				<li><a href="<?php echo get_category_link($ancestor); ?>"><?php echo get_cat_name($ancestor); ?></a></li>
				<li>&gt;</li>
			<?php endforeach; ?>
		<?php endif; ?>
	<li><?php echo $cat -> cat_name; //single_cat_title(); ?></li>
<?php elseif(is_author()): /* 投稿者 */ ?>
	<li>投稿者 : <?php the_author_meta('display_name', get_query_var('author')); ?></li>
<?php elseif(is_page()): /* 固定ページ */ ?>
	<?php if($post -> post_parent != 0 ): ?>
	<?php $ancestors = array_reverse( $post-> ancestors ); ?>
	<?php foreach($ancestors as $ancestor): ?>
			<li><a href="<?php echo get_permalink($ancestor); ?>"><?php echo get_the_title($ancestor); ?></a></li>
		<li>&gt;</li>
	<?php endforeach; ?>
	<?php endif; ?>
	<li><?php echo $post -> post_title; ?></li>
<?php elseif(is_attachment()): /* 添付ファイルページ */ ?>
	<?php if($post -> post_parent != 0 ): ?>
			<li><a href="<?php echo get_permalink($post -> post_parent); ?>"><?php echo get_the_title($post -> post_parent); ?></a></li>
		<li>&gt;</li>
	<?php endif; ?>
		<li><?php echo $post -> post_title; ?></li>
<?php elseif(is_single()): /* 個別記事 */ ?>
 <?php $categories = get_the_category($post->ID); ?>
		<?php $cat = $categories[0]; ?>
	<?php if($cat -> parent != 0): ?>
		<?php $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' )); ?>
			<?php foreach($ancestors as $ancestor): ?>
				<li><a href="<?php echo get_category_link($ancestor); ?>"><?php echo get_cat_name($ancestor); ?></a></li>
				<li>&gt;</li>
			<?php endforeach; ?>
	<?php endif; ?>
		<li><a href="<?php echo get_category_link($cat -> cat_ID); ?>"><?php echo $cat-> cat_name; ?></a></li>
		<li>&gt;</li>
		<li><?php echo $post -> post_title; ?></li>
<?php else: /* 上記に当てはまらないページ */ ?>
	<li><?php wp_title('', true); ?></li>
<?php endif; ?>
</ul>
</div>
<?php endif; ?>

一番最後に、if 文で条件分岐したページに当てはまらないページの場合の処理を書き加えて(66行目)完成です。wp_title() で、ページのタイトルを表示するようにしています。

とても長いコードですねー …。このような長いコードが、header.php などのテンプレートファイルに記述されているのもメンテナンス性がよくありません。ですので functions.php に関数としてまとめてみましょう。

functions.php
<?php
function breadcrumb(){
	global $post;
	$str ='';
	if(!is_home()&&!is_admin()){ /* !is_admin は管理ページ以外という条件分岐 */
		$str.= '<div id="breadcrumb" class="clearfix">';
		$str.= '<ul>';
		$str.= '<li><a href="'. home_url() .'/">HOME</a></li>';
		$str.= '<li>&gt;</li>';
		
		if(is_search()){
			$str.='<li>「'. get_search_query() .'」で検索した結果</li>';
		} elseif(is_tag()){
			$str.='<li>タグ : '. single_tag_title( '' , false ). '</li>';
		} elseif(is_404()){
			$str.='<li>404 Not found</li>';
		} elseif(is_date()){
			if(get_query_var('day') != 0){
				$str.='<li><a href="'. get_year_link(get_query_var('year')). '">' . get_query_var('year'). '年</a></li>';
				$str.='<li>&gt;</li>';
				$str.='<li><a href="'. get_month_link(get_query_var('year'), get_query_var('monthnum')). '">'. get_query_var('monthnum') .'月</a></li>';
				$str.='<li>&gt;</li>';
				$str.='<li>'. get_query_var('day'). '日</li>';
			} elseif(get_query_var('monthnum') != 0){
				$str.='<li><a href="'. get_year_link(get_query_var('year')) .'">'. get_query_var('year') .'年</a></li>';
				$str.='<li>&gt;</li>';
				$str.='<li>'. get_query_var('monthnum'). '月</li>';
			} else {
				$str.='<li>'. get_query_var('year') .'年</li>';
			}
		} elseif(is_category()) {
			$cat = get_queried_object();
			if($cat -> parent != 0){
				$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' ));
				foreach($ancestors as $ancestor){
					$str.='<li><a href="'. get_category_link($ancestor) .'">'. get_cat_name($ancestor) .'</a></li>';
					$str.='<li>&gt;</li>';
				}
			}
			$str.='<li>'. $cat -> name . '</li>';
		} elseif(is_author()){
			$str .='<li>投稿者 : '. get_the_author_meta('display_name', get_query_var('author')).'</li>';
		} elseif(is_page()){
			if($post -> post_parent != 0 ){
				$ancestors = array_reverse(get_post_ancestors( $post->ID ));
				foreach($ancestors as $ancestor){
					$str.='<li><a href="'. get_permalink($ancestor).'">'. get_the_title($ancestor) .'</a></li>';
					$str.='<li>&gt;</li>';
				}
			}
			$str.= '<li>'. $post -> post_title .'</li>';
			
		} elseif(is_attachment()){
			if($post -> post_parent != 0 ){
				$str.= '<li><a href="'. get_permalink($post -> post_parent).'">'. get_the_title($post -> post_parent) .'</a></li>';
				$str.='<li>&gt;</li>';
			}
			$str.= '<li>' . $post -> post_title . '</li>';
		} elseif(is_single()){
			$categories = get_the_category($post->ID);
			$cat = $categories[0];
			if($cat -> parent != 0){
				$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' ));
				foreach($ancestors as $ancestor){
					$str.='<li><a href="'. get_category_link($ancestor).'">'. get_cat_name($ancestor). '</a></li>';
					$str.='<li>&gt;</li>';
				}
			}
			$str.='<li><a href="'. get_category_link($cat -> term_id). '">'. $cat-> cat_name . '</a></li>';
			$str.='<li>&gt;</li>';
			$str.= '<li>'. $post -> post_title .'</li>';
		} else{
			$str.='<li>'. wp_title('', false) .'</li>';
		}
		$str.='</ul>';
		$str.='</div>';
	}
	echo $str;
}
?>

今度は作成したパンくずリストの関数を header.php の中に記述します。

  • 1. <?php breadcrumb(); ?>

記述はたったの 1行ですね!この一行で、関数 breadcrumb() が実行され、パンくずリストが表示されますから、header.php はスッキリしますね!

MEMO

@ワテさんが Gist にキレイにまとめてくれました!こっちの方が見やすいです!若干改修されてますが、こっちの方がおすすめです ;D


ここまではパンくずリストを作成しながら、ページのいろいろな情報を取得して利用するための流れを見てきました。$wp_query$post という変数を参照して利用する方法や、現在操作している要素の親要素祖先要素を取得したりしてみました。

WordPress でのサイト構築では、条件分岐で表示されているページごと、何かしら関連するページを取得して表示するケースはたくさんあります。パンくずリストの作成ステップには、それらに応用できるノウハウが盛り込まれているんじゃないかなーと思います。

また WordPress では、カテゴリーやタグ、記事などのオブジェクトには、ひとつひとつ一意な ID がつけられています。そしてこの ID を軸として、いろいろな値を取得したり、表示したりする作業が WordPress でのサイト構築ではよく使われるテクニックですね!

12. サイドバーのローカルナビに応用する

さて、ここからが応用編です。パンくずリストの作成では、現在のページから、関連するページ(主に祖先)を取得して表示させてきました。今度はこれを応用して、サイドバーで固定ページの子ページや兄弟ページを表示するローカルナビゲーションを作ってみます。

サイドバーのローカルナビゲーション

サイドバーに子ページを表示する

「事業内容」という親ページで、3つの子ページへのリンクを表示しています。

今回編集するのは、sidebar.php。まずは骨組みとして、条件分岐で親ページと子ページを分けてしまいましょう。

1 STEP 1
<div id="sidebar">
<aside id="local-navi">
<?php global $post;
if(is_page()): ?>
<?php if($post->post_parent == 0): ?>
	親ページの時
<?php else: ?>
	子ページの時
	<?php endif;
endif; ?>
</aside>
</div>

大枠の条件分岐「固定ページかどうか」is_page() を使って条件分岐します。Webサイト全体から見れば、ブログページや検索結果ページなど、多数のページが存在しますから、まずは大きく「固定ページ」で分けておきます。

続く内側の条件分岐を見てみましょう。$post->post_parent が「0」の場合は、親ページを持っていないことを意味します。なので現在表示されているのは、親ページを持たない(それ自身が親ページ)ページという判断に利用できますね。

これで大枠ができました!それでは条件分岐内に、タイトルやリンクを表示していきます!親ページの場合と、子ページの場合ではコードが違うので、順番にチェックしていきますね!

12.1. 親ページの場合

親ページの場合は、まず親ページのタイトルを表示して、その下に子ページをリストで表示していきます。HTML で見ると以下のようになります。

目指すHTML
<ul>
	<li class="current">親ページ				
	<ul class="child">
	<li><a href="#">子ページ#1</a></li>
	<li><a href="#">子ページ#2</a></li>
	<li><a href="#">子ページ#3</a></li>
	</ul>
	</li>
</ul>

親ページの li 要素の中に、子ページを ul、li 要素で入れ子のリストにします。それでは PHP のコードを見ていきましょう。

2 STEP 2
<?php if(is_page()): ?>
	<?php if ( $post->post_parent == 0 ) : /* 親ページの場合 */ ?>				
	<?php 
	$args = array(
		'post_type' => 'page',
		'post_parent' => $post->ID
	); 
	$child_posts = new WP_Query( $args ); 
		<?php if( $child_posts -> have_posts() ): 
			while ($child_posts -> have_posts()) : $child_posts -> the_post(); ?>

			ここに子ページを表示するサブループ
	
			<?php endwhile;
		endif; wp_reset_postdata(); ?>
	endif; 
endif; ?>

子ページを表示するために、サブループを作成していきます。今回は WP_Query を使ったサブループを作成しました。

CHECK

サブループって何?という人は、過去記事で詳しく書いているので、そちらをを参照してみてくださいね!

まずはサブループに渡すパラメータを、配列 $args に記述にしていきます。post_typepage を指定することで、固定ページのみを取得できます。そして post_parent に、$post -> ID を指定すると、現在表示されている($post -> ID)ページを親に持つページを取得できます。

$args = array(
	'post_type' => 'page',
	'post_parent' => $post -> ID
); 

それではサブループの中、子ページのタイトルやパーマリンクを取得していきます。

3 STEP 3

<?php if(is_page()): ?>
<?php if ( $post->post_parent == 0 ) : /* 親ページの場合 */ ?>				
	<?php 
		$args = array(
			'post_type' => 'page',
			'post_parent' => $post->ID
	); 			
	$child_posts = new WP_Query( $args ); 
	if( $child_posts -> have_posts() ): ?>
<nav class="structure">
<ul>
<li class="current"><?php echo $post -> post_title; /* 親ページのタイトル */ ?>
	<ul class="child">
	<?php while ($child_posts -> have_posts()) : $child_posts -> the_post(); /* ここから子ページのループ */?>
		<li><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></li>
	<?php endwhile;?>
	</ul>
</li>
</ul>
</nav>
<?php endif; wp_reset_postdata(); 
endif;
endif; ?>

タイトルやリンクの取得は、the_title()the_permalink() を使って表示します。ここはループの中なので、ループ内で使えるテンプレートタグを使用します。注意するのは、リストのマークアップですね!

12行目は親ページのタイトルを表示するコードです。これはループ外に記述します!なのでループ内で使う the_title() ではなくて、$post -> post_title でタイトルを表示しています。

MEMO

今回は単純にタイトルやパーマリンクを取得しているだけのサブループですが、echo get_the_post_thumbnail($post -> ID) などとして、アイキャッチ画像を表示させたりすることも簡単にできますね!

これで親ページの時のサイドバーは完成です!

12.2. 子ページの場合

子ページのときは、さっきとは表示したいページの関係性が変わります。さっきは「子ページ」を表示しましたが、今度は兄弟にあたるページを表示していきます!

子ページ時の表示

兄弟ページを表示するローカルナビ

表示するのは兄弟関係にあるページになります!

4 STEP 4
<?php if(is_page()):?>
<?php if ( $post->post_parent == 0 ) : /* 親ページの場合 */ ?>
	親ページのときの処理
<?php else: /* 子ページの場合 */
$args = array(
	'post_type' => 'page',
	'post_parent' => $post -> post_parent
);
				
$current_ID = $post->ID;

$brother_posts = new WP_Query( $args );
	if( $brother_posts -> have_posts() ): ?>
			<nav class="structure">
			<ul>
		<?php while ($brother_posts -> have_posts()) : $brother_posts -> the_post(); /* 兄弟ページのループ */
			if($current_ID == $post->ID): ?>
				<li class="current"><span><?php the_title(); ?></span></li>
			<?php else: ?>
   				<li class="brother"><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></li>
    		<?php endif;  ?>
		<?php endwhile;?>
			</ul>
			</nav>
	<?php endif; wp_reset_postdata();		
endif; ?>

まずは if ( $post->post_parent == 0 ) : /* 親ページの場合 */ で始まっている条件分岐を else: でつないで、「子ページの場合」の処理を記述していきます。

親ページのときと同じように、サブループを作って兄弟ページを表示していきます。サブループに渡すパラメータは先ほどと少し違います。

  • 7. 'post_parent' => $post -> post_parent

上記のようにすれば、現在表示されているページ(子ページ)の親ページを親に持つページ … つまり同じ階層の兄弟ページを取得できます。少しややこしいですが、落ち着いて整理してみてくださいね!

あとは基本的には親ページ時のときのコードと同じです(入れ子にはしてませんが …)。現在表示されているアクティブなページはリンクにする必要がないので、current というクラスをつけて、span 要素でアークアップしてみました。

これで子ページの場合のサイドバーは完成です!

それぞれのサイドバー

表示したいページが同じでも、取得方法が違います!


実際にパンくずリストを Webサイトに設置するのには、Breadcrumb NavXT といったプラグインを利用したりするのも、もちろんアリですよね!でも、こんな風にしてパンくずリストを自作してみると、WordPress でのサイト構築に必要なテクニックというか、ノウハウみたいなものがたくさん詰まっていました。

こんな風にして祖先ページ子ページ兄弟ページを取得して表示する方法を覚えてしまうと、サイドバー作りも楽しくなってきます!もちろんサイドバー以外の部分 … 例えば記事下で「関連記事を表示」みたいにしても OK です。

ATTENTION

今回はパンくずリストを作ることが目的じゃなくて、パンくずリストのコードから、WordPress でのサイト構築のノウハウを勉強するっていう主旨の記事でした。実際にパンくずリストを表示するコードは、もっとスマートに書くこともできます。なので、コード自体は参考という感じで読み解いてみてください!

Comments

Thank you for the comment.