テーマにナビゲーションメニューを追加する方法|register_nav_menus と表示手順

結論

クラシックテーマにメニューを追加するには、次の3か所を作ります。

  1. functions.php の after_setup_theme で register_nav_menus() を呼び、メニュー位置を登録する
  2. テンプレートに wp_nav_menu( array( 'theme_location' => '位置名' ) ) を書く
  3. 管理画面の「外観 > メニュー」で、メニューを作り、位置に割り当てる

「メニューが出ない」「固定ページの一覧が出てしまう」原因の多くは、位置にメニューが未割り当てであることです。fallback_cb を false にすると、未割り当て時は何も出力しなくなります。

原因・仕組み

register_nav_menus() は「位置」の名前を登録するだけで、メニュー自体は作りません。wp_nav_menu() は、theme_location に割り当てられたメニューを探し、なければ fallback_cb(既定は wp_page_menu)を呼びます。公式リファレンスによると、メニュー指定→位置の割り当て→最初の空でないメニュー→fallback_cb の順に探し、見つからず fallback_cb もなければ false を返します。

そのため、割り当てを忘れても、エラーではなく「固定ページの一覧」がフォールバックとして表示されます。

手順(サンプルコード)

1. メニュー位置を登録する

add_action( 'after_setup_theme', function () {
    register_nav_menus( array(
        'primary' => 'メイン',
        'footer'  => 'フッター',
    ) );
} );

2. テンプレートで表示する

<?php if ( has_nav_menu( 'primary' ) ) : ?>
    <?php
    wp_nav_menu( array(
        'theme_location'  => 'primary',
        'container'       => 'nav',
        'container_class' => 'gnav',
        'menu_class'      => 'gnav__list',
        'depth'           => 1,
        'fallback_cb'     => false,
    ) );
    ?>
<?php endif; ?>

has_nav_menu() で割り当て済みか確認すれば、未設定の場合に空の <nav> を出さずに済みます。

3. 管理画面で割り当てる

「外観 > メニュー」でメニューを作成し、「メニューの設定」の表示場所にチェックします(ブロックテーマでは別の画面になります)。コードで作るなら、wp_create_nav_menu()、wp_update_nav_menu_item()、set_theme_mod( 'nav_menu_locations', ... ) を使います。

動作確認(検証環境と結果)

WordPress 7.1.2(ja)、PHP 8.2.12 の CLI 環境で、一時メニューを作成して確認し、終了時に削除しました。

  • 登録直後、has_nav_menu( 'primary' ) は false。
  • 未割り当てで wp_nav_menu を呼ぶと、<div class="menu"><ul><li class="page_item ...">サンプルページ</li></ul></div>(固定ページ一覧)が返った。
  • fallback_cb => false では false(出力なし)。
  • メニューを作成して primary に割り当てると、has_nav_menu( 'primary' ) は true、footer は false。
  • container => 'nav'、menu_class => 'gnav__list'、depth => 1 で、<nav class="gnav"><ul id="menu-p1-tmp-menu" class="gnav__list">... が出力された。
  • 削除後、wp_get_nav_menu_object は false。

ログは testsadd-navigation-menu-theme-register-nav-menus.md にあります。ブラウザでの管理画面操作は、この環境では行っていません。

テーマにナビゲーションメニューを追加する方法の注意点

  • register_nav_menus() は、テーマ機能の宣言として after_setup_theme にまとめて書くのが一般的です(after_setup_theme フックの使い方|説明・引数・注意点参照)。公式リファレンスのユーザー投稿ノートには init で呼ぶ例もあり、どちらでも動作します。
  • メニューの割り当て(nav_menu_locations)はテーマごとに保存されるため、テーマを切り替えると割り当てが外れることがあります。
  • container に使えるのは、既定では div と nav です。
  • ブロックテーマでは、ナビゲーションブロックを使うため、この手順は不要な場合があります。

テーマにナビゲーションメニューを追加する方法でよくあるミス

  • 位置を登録しただけで、管理画面で割り当てない。
  • theme_location の名前が、登録時と違う(primary と main など)。
  • 位置名(スラッグ)を後から変更し、割り当て済みのメニューが表示されなくなる(公式にも注意書きあり)。子テーマで扱うときは子テーマと functions.phpも参照。
  • $html = wp_nav_menu( ... ) と変数に入れて加工しようとして、echo => false を指定し忘れる。既定(echo => true)では、その場で出力され、戻り値は値を持ちません(検証では NULL)。

テーマにナビゲーションメニューを追加する方法のチェックリスト

  • [ ] register_nav_menus() を after_setup_theme で呼んだか
  • [ ] theme_location の名前が一致しているか
  • [ ] 管理画面で位置に割り当てたか
  • [ ] fallback_cb の方針を決めたか
  • [ ] depth やクラス名がデザインと合っているか

テーマにナビゲーションメニューを追加する方法のFAQ(よくある質問)

Q. メニューが空のとき、何も出したくありません。
A. fallback_cb => false にするか、has_nav_menu() で囲みます。

Q. メニューのHTMLを細かく変えたいです。
A. walker を渡す方法と、nav_menu_css_class などのフィルターを使う方法があります。

Q. 複数の位置を登録するのに、関数は1つで足りますか?
A. register_nav_menus() に連想配列で渡せば足ります。

筆者の見解(テーマにナビゲーションメニューを追加する方法)

メニューの不具合は、コードより「割り当て忘れ」であることが多いと考えます。まず has_nav_menu() で状態を確かめ、その上で fallback_cb を false にしておくと、未設定のときの挙動が分かりやすくなります。納品時には、位置の名前と割り当て手順を、簡単にでもまとめておくと親切だと思います。

テーマにナビゲーションメニューを追加する方法の関連項目

出典(一次情報)

タイトルとURLをコピーしました