2026年6月17日

2026年6月17日

WordPressのナビゲーションメニューをカスタマイズする方法・Walker・動的メニュー

はじめに

「ナビゲーションにアイコンやバッジを追加したい」「ログイン状態でメニューを変えたい」——WordPressのナビゲーションメニューはWalkerクラスをカスタマイズすることで高度な表示制御が可能です。

症状・原因

デフォルトのwp_nav_menu()はシンプルなHTMLを出力しますが、BootstrapのドロップダウンやメガメニューなどフレームワークのHTML構造に合わせるには、Walker_Nav_Menuクラスを拡張する必要があります。

解決手順

ステップ1:メニュー位置を登録する

// テーマのfunctions.phpにメニュー位置を登録
add_action( 'init', function() {
    register_nav_menus( [
        'primary'   => 'グローバルナビゲーション',
        'footer'    => 'フッターメニュー',
        'mobile'    => 'モバイルメニュー',
        'social'    => 'ソーシャルメニュー',
    ] );
} );
管理画面でのメニュー割り当て:
  外観 → メニュー → メニューを編集
  → 「メニューの設定」セクション
  → テーマの位置: 「グローバルナビゲーション」にチェック
  → 「メニューを保存」

ステップ2:wp_nav_menu()でメニューを表示する

// 基本的なメニュー表示
wp_nav_menu( [
    'theme_location' => 'primary',
    'menu_class'     => 'nav-menu',
    'container'      => 'nav',
    'container_class' => 'main-navigation',
    'depth'          => 2,          // 2階層まで表示
    'fallback_cb'    => false,      // メニュー未設定時に何も表示しない
] );

// メニューにBootstrapクラスを追加
wp_nav_menu( [
    'theme_location' => 'primary',
    'menu_class'     => 'navbar-nav',
    'container'      => false,
    'items_wrap'     => '<ul id="%1$s" class="%2$s">%3$s</ul>',
] );

ステップ3:WalkerクラスでカスタムHTML構造を生成する

// BootstrapドロップダウンHTML構造に対応したWalker
class Bootstrap_Nav_Walker extends Walker_Nav_Menu {

    public function start_lvl( &$output, $depth = 0, $args = null ) {
        $output .= '<ul class="dropdown-menu">';
    }

    public function start_el( &$output, $item, $depth = 0, $args = null, $id = 0 ) {
        $classes     = empty( $item->classes ) ? [] : (array) $item->classes;
        $has_children = in_array( 'menu-item-has-children', $classes );

        $class_names = 'nav-item';
        if ( $has_children ) $class_names .= ' dropdown';
        if ( in_array( 'current-menu-item', $classes ) ) $class_names .= ' active';

        $output .= '<li class="' . esc_attr( $class_names ) . '">';

        $link_class = 'nav-link';
        if ( $has_children ) $link_class .= ' dropdown-toggle';

        $output .= '<a href="' . esc_url( $item->url ) . '"'
            . ' class="' . $link_class . '"'
            . ( $has_children ? ' data-bs-toggle="dropdown"' : '' )
            . '>' . esc_html( $item->title ) . '</a>';
    }
}

// 使い方
wp_nav_menu( [
    'theme_location' => 'primary',
    'walker'         => new Bootstrap_Nav_Walker(),
] );

ステップ4:ログイン状態でメニューを動的に変更する

// ログイン状態に応じてメニューアイテムを追加
add_filter( 'wp_nav_menu_items', function( $items, $args ) {
    if ( $args->theme_location !== 'primary' ) return $items;

    if ( is_user_logged_in() ) {
        $items .= '<li class="menu-item"><a href="' . get_dashboard_url() . '">ダッシュボード</a></li>';
        $items .= '<li class="menu-item"><a href="' . wp_logout_url( home_url() ) . '">ログアウト</a></li>';
    } else {
        $items .= '<li class="menu-item"><a href="' . wp_login_url( get_permalink() ) . '">ログイン</a></li>';
    }

    return $items;
}, 10, 2 );

ステップ5:メニューアイテムにカスタムフィールドを追加する

// メニューアイテムの編集画面にアイコンフィールドを追加
add_action( 'wp_nav_menu_item_custom_fields', function( $item_id, $item ) {
    $icon = get_post_meta( $item_id, '_menu_item_icon', true );
    wp_nonce_field( 'menu_item_icon_nonce', 'menu_item_icon_nonce' );
    echo '<p class="field-icon">';
    echo '<label>アイコン(Font Awesome例: fa-home)</label>';
    echo '<input type="text" name="menu-item-icon[' . $item_id . ']"'
        . ' value="' . esc_attr( $icon ) . '">';
    echo '</p>';
}, 10, 2 );

// 保存処理
add_action( 'wp_update_nav_menu_item', function( $menu_id, $menu_item_db_id ) {
    if ( ! isset( $_POST['menu_item_icon'][ $menu_item_db_id ] ) ) return;
    if ( ! wp_verify_nonce( $_POST['menu_item_icon_nonce'], 'menu_item_icon_nonce' ) ) return;
    update_post_meta(
        $menu_item_db_id,
        '_menu_item_icon',
        sanitize_text_field( $_POST['menu_item_icon'][ $menu_item_db_id ] )
    );
}, 10, 2 );

// Walker内でアイコンを表示
// $icon = get_post_meta( $item->ID, '_menu_item_icon', true );
// if ( $icon ) $output .= '<i class="fas ' . esc_attr( $icon ) . '"></i> ';

注意事項

  • Walker_Nav_Menuを拡張する場合、WordPressのバージョンアップでWalkerクラスのメソッドシグネチャが変わることがあります。$argsパラメータのデフォルト値(= null)を設定しておくと互換性が保たれます。
  • メガメニューのような複雑なHTML構造は、Walkerクラスではなくwp_nav_menu_itemsフィルターや専用のメガメニュープラグイン(Max Mega Menu等)を使う方が保守性が高い場合があります。
  • register_nav_menus()after_setup_themeアクションで呼び出すのが正しい方法です。initフックでも動作しますが、テーマの初期化タイミングに合わせるためafter_setup_themeが推奨です。

まとめ

ナビゲーションメニューのカスタマイズは「メニュー位置登録→wp_nav_menu()表示→Walkerクラス拡張→動的メニュー変更→カスタムフィールド追加」の順で実装できます。Bootstrap等のCSSフレームワークとの統合にはWalkerクラスが強力です。関連記事:WordPressでウィジェットをカスタマイズする方法WordPressのfunctions.phpを安全に編集する方法

お気軽にご相談ください

お見積りへ お問い合わせへ