「管理画面からメニューを作成したいけど、どこから作業すれば良いかわからない」
「メニューを設定したはずなのに画面に表示されないことがあって原因がわからない」
「プログラムができない人でも運用できるようなメニューを作成したい」
本日はそんな方に向けてWordPressにおけるメニューの設定方法をお話ししていきます。
WordPressを使用してウェブサイトを構築する際に、ナビゲーションメニューは重要な要素の一つです。
しかし初めてWordPressを使う人にとっては、メニューの作成や管理方法が少々複雑に感じられるかもしれません。
そこで今回はWordPressでメニューを作成する際の王道パターンを紹介します。
home_url
、register_nav_menus
、get_nav_menu_locations
、wp_get_my_object
、wp_get_nav_menu
などの重要な関数やコンセプトに焦点を当てながら、効果的なメニューの作成方法を解説します。
WordPress初心者でも迷わずに、ウェブサイトのナビゲーションをカスタマイズできるようになることでしょう。
また動画もあるので必要に応じて活用してください。
メニューのリンクを出力するのはhome_urlを使う
一番簡単な方法としてはhome_urlというテンプレート関数を使うものです。
home_urlは使用するテンプレートファイルを起点にした相対パスを引数に文字列で指定してあげることで、そのページまでのURLを出力してくれるものです。
こちらをaタグのhrefに入れることでドメインが変わってもテンプレートファイルの構成さえ同じであれば運用できるメニューとして活用できます。
<nav class="header_nav">
<ul class="header_nav-1">
<li><a href="<?php echo esc_url(home_url('/'));?>">ホーム</a></li>
<li><a href="<?php echo esc_url(home_url('/blogs'));?>">ブログ</a></li>
<li><a href="<?php echo esc_url(home_url('/category/programming'));?>">プログラミング</a></li>
<li><a href="<?php echo esc_url(home_url('/rpa'));?>">RPA</a></li>
<li><a href="<?php echo esc_url(home_url('/mental'));?>">メンタル</a></li>
<li><a href="<?php echo esc_url(home_url('/career'));?>">キャリア活動</a></li>
<li><a href="<?php echo esc_url(home_url('/contents'));?>">コンテンツ</a></li> -->
</ul>
</nav>
難点としてはメニュー項目の数だけ記載しないといけなくて、スマホ用とPC用でメニュー要素を別で作っている場合はメニュー項目の2倍の数だけ設定する場所があることです。
またテンプレートファイルの構成が変わったり、ファイル名が変わった場合にはhome_urlの引数を変更しなければなりません。
単純な方法なので初心者向けですがプログラミングができないお客さんには対応できないものになるでしょう。
管理画面から編集できるようにするにはregister_nav_menusを使う
投稿ページや固定ページのように管理画面からメニューを編集できるようにする方法があります。
functions.phpにregister_nav_menusという関数を記載します。
引数は配列にして作成したメニューの位置を指定します。
メニューの位置はキーと値で以下のように指定して、ヘッダー用とフッター用を作ることが多いです。
<?php
function add_custom_menu(){
// 外観に「メニュー」を追加する
register_nav_menus([
// メニュー位置の名称(メニューを作成して保存する)
'header_nav' => 'ヘッダーメニュー',
'footer_nav' => 'フッターメニュー',
]);
}
add_action("init", "add_custom_menu");
?>
管理画面をリロードすると「外観」に「メニュー」が追加されているはずです。

こちらをクリックするとメニューを編集する画面が表示されます。
左のパネルでメニューに表示する候補を表示してくれていて、投稿ページ、固定ページ、カテゴリー、カスタムリンクがあります。
カスタムリンクはSNSなど外部サイトのリンクを設定するように用意されています。
それぞれの候補がチェックボックスになっていますので追加したいものをチェックして「メニューに追加」をクリックすると右側のパネルに表示されます。


右側のパネルの下部にある「メニュー設定」という場所のチェックボックスで今作っているメニューリストをどの位置に表示したいかを選択して「メニューを保存」をクリックすればメニューリストが1つ作成されたことになります。

上図ではフッターメニューを作成していたのですが、同じような手順でメニューリストは何個でも作成できます。
たくさんのメニューリストを作成すると混乱するので右側のパネル上部のメニュー名を指定して、先ほどの「メニューを保存」を再度クリックしておきます。

ヘッダーメニューも作成してみたいので新しいメニューリストを作成します。
以下の部分にある「新しいメニューを作成しましょう」をクリックすると新しい作成画面になります。

ヘッダーメニューは以下のように作成して、メニュー位置は「ヘッダーメニュー」の方にチェックを入れて保存します。
ちなみにメニュー位置の「ヘッダーメニュー」「フッターメニュー」というのはfunctions.phpで作成したregister_nav_menusの引数になります。
<?php
function add_custom_menu(){
// 外観に「メニュー」を追加する
register_nav_menus([
// メニュー位置の名称(メニューを作成して保存する)
'header_nav' => 'ヘッダーメニュー',
'footer_nav' => 'フッターメニュー',
]);
}
add_action("init", "add_custom_menu");
?>
現状としてはヘッダー用のメニューリストとフッター用のメニューリストを作成しています。
まだ画面に表示していないので、それぞれheader.phpとfooter.phpに表示します。
<?php
$locations = get_nav_menu_locations();
$menu_id = $locations["header_nav"];
$header_menus = wp_get_nav_menu_items($menu_id);
?>
<nav class="header_nav">
<ul class="header_nav-1">
<?php foreach ($header_menus as $item) : ?>
<li>
<a href="<?php echo esc_attr($item->url); ?>">
<?php echo esc_html($item->title); ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
get_nav_menu_locationsを引数なしで実行すると現時点で設定されている全てのメニュー位置が返ってきます。

今回で言うとheader_navとfooter_navの2箇所をfunctions.phpで設定していました。
さらにheader_navやfooter_navというキー名に対応する数字の値ですが、こちらはWordPress側で認識されるメニューの種類番号です。
複数のメニューを作成したときにWordPressがそれぞれのメニューリストを見分けるために使っているIDのようなものです。
そのIDをwp_get_nav_menu_objectの引数に入れることで作成されたメニューリストが返ってきます。

0から始まるインデックス番号が振られていて、各インデックス番号に対応する要素がWP_Post Objectとなっています。
このWP_Post Objectがヘッダーメニューの中の一つ一つのメニュー項目になります。
メニュー項目と言っても上図のようにいろんなプロパティによって情報が登録されています。
例えばtitleだとメニュー名で、urlだとメニューが対応するページURLです。

それらをforeachを使って1個ずつのメニュー項目を取り出してechoで画面上に表示させます。
<?php
$locations = get_nav_menu_locations();
$header_menu = wp_get_nav_menu_object($locations["header_nav"]);
$header_menu_items = wp_get_nav_menu_items($header_menu->term_id);
?>
<nav class="header_nav">
<ul class="header_nav-1">
<?php foreach ($header_menu_items as $item) : ?>
<li>
<a href="<?php echo esc_attr($item->url); ?>">
<?php echo esc_html($item->title); ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
上図のコードではliタグの中のaタグにURLと表示名を出力させているのですが、メニュー名のようなテキストはesc_htmlの中で実行して、URLはesc_urlの中で実行させることでセキュリティ対策を盛り込むことができています。

現時点でそれぞれのメニューリストに追加されている分だけのメニュー名が表示されるので、管理画面から表示名の変更や項目の削除をすると動的に反映されます。

変更や削除は作業した後に必ず「メニューの保存」をクリックして画面をリロードさせましょう。
こちらの方法だと一度作ってしまった後はプログラミングができない人でも管理画面からマウスとクリックで操作できるので運用がしやすいです。