WordPressでメニュー・カテゴリ一覧表示を作る(wp_nav_menuとwp_get_nav_menu_items)

WordPressでメニューを表示する

WordPressでメニュー表示する際、一番簡単なのは「wp_nav_menu」を利用することなんだけど、余計なクラス名がついたり、li要素にクラスを追加したりと、カスタマイズするにはやや不便かなぁ…と、少し煩雑になりますがwp_get_nav_menu_itemsの使い方をちょっと調べてみました。

wp_nav_menuを使用したケース

まずは簡単なwp_nav_menuの概要から。
functions.php内に下記のようにコードを書いてメニューの定義をします。

ひとつのメニューを定義する場合

<?php register_nav_menu( 'header_menu', 'ヘッダーのナビ名' ); ?>

複数のメニューを定義する場合

<?php
	register_nav_menus(array(
		'header_menu' => 'ヘッダーメニュー',
		'sidebar_menu' => 'サイドバーメニュー',
		'footer_menu' => 'フッターメニュー'
	));
?>

定義ができたら次はダッシュボード→外観→メニューで表示したい項目をドラッグ&ドロップで集めてやって、先ほど定義したテーマに関連付けてやります。

ここで定義したメニューのテーマ(header_menuなど)をtheme_locationに指定してあげればOK。

メニューを表示したいところに書くコード

この例ではfuncitons.phpに定義したテーマ「header_menu(アンダースコア)」とダッシュボード上で定義したメニュー名「header-menu(ハイフン)」の2種類の名前を定義しているのですが、wp_nav_menuのltheme_locationプロパティでの指定はfunctions.php内で定義した「header_menu(アンダースコア)」を指定します。
後述しますが、今回wp_get_nav_menu_itemsを使用するにあたってこの点がかなり混乱しました…

wp_nav_menuで出力されるソース

<div class="menu">
	<ul>
		<li class="page_item page-item-18">
			<a href="http://localhost/xtra-blog/about/">ABOUT</a>
		</li>
		<li class="page_item page-item-22">
			<a href="http://localhost/xtra-blog/contact/">CONTACT</a>
		</li>
		<li class="page_item page-item-20">
			<a href="http://localhost/xtra-blog/site-map/">SITE MAP</a>
		</li>
		<li class="page_item page-item-52">
			<a href="http://localhost/xtra-blog/">TOP PAGE</a>
		</li>
	</ul>
</div>

こんな具合です。 プロパティの変更やfunctions.phpへの記述でタグやクラスなどの形成はできますが、デフォルトではちょっと野暮ったいクラス指定ですよね。
デフォルトで付与されるクラス名を利用してCSS指定できるというメリットもありますが、不必要なものは減らしたほうがいいですしカスタマイズ性も良いとはいえません。

wp_get_nav_menu_itemsを使用したケース

次は本題のwp_get_nav_menu_itemsです。 最初にリファレンスを読んでおきましょう。

管理画面→外観 → メニュー 内に作られたナビゲーションメニューのアイテムを返す関数です。
この関数は、メニュー名、スラッグ、IDなど、ナビゲーションメニューのアイテムを返します。返されるメニューアイテムは、通常の投稿やページを参照している、関係する nav_menu_item タイプの投稿です。

WordPressCodex日本語版

作成したメニューから配列を返す関数になっています。 こちらの場合はダッシュボード上のメニュー構造を参照する為、functions.php上でのメニュー定義は必要ないですが、メニューを使う宣言は必要になります。

functions.phpで定義するためのコード

add_theme_support( 'menus' );

あとはwp_nav_menuの時と同じようにダッシュボード上でメニューに表示したい項目をドラッグ&ドロップで集めてください。

あとはこの配列をforeachループで配列の個数分繰り返し処理でタグを書き出すお馴染みの作業。
カテゴリ名・IDなどの情報は配列に入っているのでそこから抽出します。

メニューを表示したいところに書くコード

<ul class="menu">
		<?php
			$menu_items = wp_get_nav_menu_items('header-menu');
			if($menu_items) :
				foreach($menu_items as $menu) : setup_postdata($menu);
			?>
			<li class="menu-item"><a href="<?php echo esc_attr($menu->url); ?>"><?php echo esc_html($menu->title); ?></a>
		<?php
				endforeach;
			endif;
		wp_reset_postdata();
		?>
		</ul>

wp_get_nav_menu_itemsでのテーマ指定の注意

前述しましたがwp_nav_menuと使用するパラメータの違いに注意!
メニュー使用の宣言は必要ですが、基本的にダッシュボードの設定でだけで完結しているのは分かりやすいのではないでしょうか。

wp_get_nav_menu_itemsで出力されるソース

<ul class="menu">
    <li class="menu-item"> <a href="http://google.com">BLOG</a> </li>
    <li class="menu-item"> <a href="http://localhost/xtra-blog/contact/">CONTACT</a> </li>
    <li class="menu-item"> <a href="http://localhost/xtra-blog/about/">ABOUT</a> </li>
    <li class="menu-item"> <a href="http://localhost/xtra-blog/site-map/">SITE MAP</a> </li>
</ul>

このようにシンプルな、というか見た目通りのソースが出力されます。

カスタマイズやHTMLからの構築を考えたら断然wp_get_nav_menu_itemsのほうがいい!

例題がシンプルすぎて「この程度ならどっち使ってもいいじゃん!」って仕上がりになってしまいましたが、タグやクラスを自由に変更できてhtmlで仮組みしたソースから構築する際には、こっちのほうがかなり捗るんじゃないでしょうか。