閉じる

WordPressのwp_nav_menuでメニューを表示・カスタマイズする実装手順と実用コード

WordPressのオリジナルテーマ制作において、ナビゲーションメニューの実装は避けては通れない重要なステップです。

WordPressには「外観」メニューからユーザーが直感的にメニューを編集できる機能が備わっていますが、これをサイト上に正しく表示させるにはwp_nav_menu関数の理解が不可欠です。

本記事では、初心者から中級者のエンジニアに向けて、メニューの登録から出力、そして実務で多用される高度なカスタマイズ手法までを網羅して解説します。

2026年現在のモダンなWeb制作現場でも、柔軟なレイアウトを実現するためにこの関数の知識は依然として重要視されています。

静的なHTMLサイトをWordPress化する際や、特定のデザイン仕様に合わせてメニュー構造を最適化したい場合に、ぜひこの記事を参考にしてください。

WordPressでメニュー機能を利用するためには、まずテーマ側で「メニュー機能を使用する」という宣言を行う必要があります。

この宣言を行わない限り、管理画面の「外観」の中に「メニュー」という項目が表示されません。

functions.phpでのメニュー登録

メニューを登録するには、register_nav_menus関数を使用します。

この関数を使用することで、テーマ内のどの位置にメニューを表示させるかを定義できます。

PHP
// functions.phpに記述するコード
function my_theme_setup() {
    register_nav_menus( array(
        'primary' => 'メインナビゲーション',
        'footer'  => 'フッターナビゲーション',
        'mobile'  => 'モバイル用メニュー',
    ) );
}
add_action( 'after_setup_theme', 'my_theme_setup' );

上記のコードでは、3つのメニュー位置を定義しています。

'primary''footer'といったキー名は、プログラム内でメニューを呼び出す際に使用する識別子となります。

右側の文字列(メインナビゲーションなど)は、管理画面上でユーザーが確認するための表示名です。

管理画面でのメニュー作成

コードを記述した後は、WordPressの管理画面にログインし、「外観」>「メニュー」へと進みます。

そこで新しいメニューを作成し、表示したい固定ページやカスタムリンクを追加してください。

最後に、画面下部の「メニューの位置」セクションで、先ほど登録した識別子(メインナビゲーションなど)にチェックを入れて保存します。

メニューの準備が整ったら、テーマのテンプレートファイル(header.phpなど)で表示処理を記述します。

最もシンプルな記述方法は、引数に識別子を渡す方法です。

基本の出力コード

以下のコードを、メニューを表示させたい場所に記述してください。

PHP
<?php
wp_nav_menu( array(
    'theme_location' => 'primary',
) );
?>

theme_locationには、register_nav_menusで設定したキーを指定します。

この記述だけで、WordPressは管理画面で設定されたメニュー項目をHTMLとして出力してくれます。

デフォルトで出力されるHTML構造

特別な設定をしない場合、以下のようなHTML構造が出力されます。

実行結果
<div class="menu-container">
    <ul id="menu-main" class="menu">
        <li class="menu-item"><a href="/">ホーム</a></li>
        <li class="menu-item"><a href="/about">私たちについて</a></li>
        <li class="menu-item"><a href="/contact">お問い合わせ</a></li>
    </ul>
</div>

デフォルトでは<div>タグでラップされ、その中に<ul>タグが生成されます。

しかし、実際の制作現場では特定のクラス名が必要だったり、不要なタグを削除したかったりすることが多いでしょう。

wp_nav_menuは、連想配列形式で多くのパラメーターを受け取ることができ、出力を細かく制御できます。

よく使われるパラメーターを以下の表にまとめました。

パラメーター名説明デフォルト値
theme_location表示するメニューの位置を指定します。なし
containerulを囲むタグを指定します(div, navなど)。不要な場合はfalse。div
container_classコンテナタグに付与するCSSクラス名。menu-{menu slug}-container
menu_classulタグに付与するCSSクラス名。menu
menu_idulタグに付与するID。なし
depth階層の深さを指定します(0はすべて、1は親のみ)。0
fallback_cbメニューが存在しない場合に呼ばれる関数。wp_page_menu
items_wrapulタグ全体の構造をカスタマイズします。%3$s

これらのパラメーターを駆使することで、既存のデザインに合わせたHTML構造へ柔軟に変更することが可能になります。

実戦的なカスタマイズ例

ここからは、実務で頻繁に要求される具体的なカスタマイズパターンを紹介します。

不要なコンテナを削除してnavタグに変更する

HTML5のセマンティックなコーディングを行う場合、<div>ではなく<nav>タグで囲むのが一般的です。

PHP
<?php
wp_nav_menu( array(
    'theme_location' => 'primary',
    'container'      => 'nav',
    'container_class'=> 'global-nav',
    'menu_class'     => 'nav-list',
) );
?>

この設定により、<nav class="global-nav">の中に<ul class="nav-list">が含まれる構造になります。

メニューが存在しない場合の余計な出力を防ぐ

デフォルトではメニューが未設定の場合、固定ページの一覧が代わりに出力されてしまいます。

これを防ぎ、何も表示させたくない場合はfallback_cbfalseを指定します。

PHP
<?php
wp_nav_menu( array(
    'theme_location' => 'primary',
    'fallback_cb'    => false,
) );
?>

この設定は、開発中の意図しない表示崩れを防ぐために非常に推奨される設定です。

特定のCSSフレームワークに合わせたクラスの追加

BootstrapやTailwind CSSを使用している場合、<li>タグや<a>タグに直接クラスを付与したいことがあります。

WordPressの標準機能だけでは<a>タグへのクラス付与が難しいため、フィルターフックを活用します。

liタグにクラスを追加する

nav_menu_css_classというフィルターを使用します。

PHP
// functions.phpに記述
function my_nav_menu_li_class($classes, $item, $args) {
    if (isset($args->add_li_class)) {
        $classes[] = $args->add_li_class;
    }
    return $classes;
}
add_filter('nav_menu_css_class', 'my_nav_menu_li_class', 1, 3);

このフックを定義しておくと、wp_nav_menuの引数に独自のキーを追加してクラスを指定できるようになります。

PHP
// テンプレート側
wp_nav_menu( array(
    'theme_location' => 'primary',
    'add_li_class'   => 'nav-item', // 独自に追加したパラメーター
) );

aタグにクラスを追加する

リンクタグそのものを加工するには、nav_menu_link_attributesフィルターを使用するのが最もスマートです。

PHP
// functions.phpに記述
function my_nav_menu_a_class($atts, $item, $args) {
    if (isset($args->add_a_class)) {
        $atts['class'] = $args->add_a_class;
    }
    return $atts;
}
add_filter('nav_menu_link_attributes', 'my_nav_menu_a_class', 1, 3);

同様に、テンプレート側で'add_a_class' => 'nav-link'のように指定すれば、すべてのリンクにクラスが付与されます。

Walkerクラスを用いた高度なHTMLカスタマイズ

さらに複雑な構造、例えばメガメニューやアイコン付きのメニューを作成したい場合は、Walker_Nav_Menuクラスを継承したカスタムクラスを作成する必要があります。

Walkerクラスを使用すると、WordPressがHTMLを生成するプロセスそのものを上書きできます。

カスタムWalkerの基本構造

以下は、各メニュー項目の説明文(Description)をリンク内に表示させるためのカスタムWalkerの例です。

PHP
class My_Custom_Walker extends Walker_Nav_Menu {
    // 各項目の開始タグ(liとa)をカスタマイズ
    function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
        
        $output .= '<li class="' . esc_attr($class_names) . '">';

        $attributes = ' href="' . esc_attr($item->url) . '"';
        
        $item_output = $args->before;
        $item_output .= '<a' . $attributes . '>';
        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        
        // メニューの説明文があれば追加
        if (!empty($item->description)) {
            $item_output .= '<span class="menu-desc">' . esc_html($item->description) . '</span>';
        }
        
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }
}

カスタムWalkerの呼び出し方

作成したクラスは、wp_nav_menuの引数walkerにインスタンスを渡すことで適用されます。

PHP
<?php
wp_nav_menu( array(
    'theme_location' => 'primary',
    'walker'         => new My_Custom_Walker(),
) );
?>

これにより、通常のメニュー出力では不可能だった自由自在なHTMLマークアップが実現します。

メニューのアクセシビリティとレスポンシブ対応

2026年のWeb制作において、アクセシビリティへの配慮は欠かせません。

wp_nav_menuで出力されるメニューを、スクリーンリーダーやキーボード操作に対応させるためのポイントを解説します。

ARIA属性の付与

ナビゲーションにはaria-labelなどを付与し、その役割を明示することが推奨されます。

コンテナタグを使用している場合は、以下のように設定すると良いでしょう。

PHP
wp_nav_menu( array(
    'theme_location' => 'primary',
    'container'      => 'nav',
    'container_aria_label' => '主要ナビゲーション',
) );

ドロップダウンメニューの制御

多階層メニュー(ドロップダウン)を実装する場合、CSSの:hoverだけで制御すると、キーボード操作のユーザーがメニューにアクセスできなくなります。

JavaScriptを組み合わせて、フォーカスが当たった際に.is-openなどのクラスを付与する実装を併用しましょう。

また、親メニューにaria-haspopup="true"aria-expanded="false"を動的に付与することで、支援技術を利用するユーザーにとっても使いやすいサイトになります。

よくあるトラブルと解決策

実装中によく遭遇する問題とその対処法についてまとめました。

メニューを更新したのに反映されない

まず疑うべきは、キャッシュプラグインやサーバー側のキャッシュです。

それらが問題ない場合、管理画面で「メニューの位置」に正しくチェックが入っているかを再確認してください。

複数のメニューを作成している場合、別のメニューを編集している可能性もよくあります。

特定のページだけメニュー項目を非表示にしたい

CSSのクラスを利用するのが最も簡単です。

WordPressは各メニュー項目に対して、menu-item-123といった固有のIDクラスを自動で付与します。

特定のページのbodyクラスと組み合わせて、.page-id-10 .menu-item-123 { display: none; }のように制御することが可能です。

もしPHP側で制御したい場合は、wp_get_nav_menu_items関数を使用して配列として取得し、条件分岐でループを回す手法を検討してください。

アクティブな項目(現在のページ)のスタイルを変えたい

WordPressは、現在表示しているページのメニュー項目にcurrent-menu-itemというクラスを自動的に付与します。

これをCSSで指定するだけで、ナビゲーションの現在地表示を実装できます。

CSS
.current-menu-item > a {
    color: #cf2e2e;
    font-weight: bold;
    border-bottom: 2px solid #cf2e2e;
}

親カテゴリーやカスタム投稿のアーカイブページなどの場合も、current-page-ancestorなどの便利なクラスが付与されるため、これらを活用しましょう。

まとめ

WordPressのwp_nav_menu関数は、単にメニューを表示するだけでなく、高度なカスタマイズを可能にする強力なツールです。

基本的なtheme_locationの指定から始まり、各種パラメーターによる構造変更、さらにフィルターフックやWalkerクラスを用いた独自の実装まで、段階的に理解を深めることが大切です。

適切なマークアップとアクセシビリティへの配慮を行うことで、ユーザーにとっても検索エンジンにとっても優しいナビゲーションを構築できます。

今回紹介したコードや手法を活用し、プロジェクトの要件に合わせた最適なメニューを実装してください。

もし将来的にブロックテーマへ移行する場合でも、これらのロジックを理解していることは、ハイブリッドテーマの構築やメンテナンスにおいて大きなアドバンテージとなるはずです。

URLをコピーしました!