カスタムメニュー機能とは?

WordPressサイトを運営していて「メニューをもっと自由にカスタマイズしたい」と思うことはありませんか?
WordPressのカスタムメニュー機能は、サイトのナビゲーションメニューを自由に作成・配置できる仕組みです。この記事では、WordPressのカスタムメニュー機能とそのカスタマイズ方法について、初心者の方にもわかりやすく解説します。

    基本的な機能

    • 管理画面の「外観」→「メニュー」から簡単に操作できる
    • ページ、投稿、カテゴリー、カスタムリンクなどを自由に組み合わせられる
    • ドラッグ&ドロップで並び替えや階層構造の作成が可能
    • 複数のメニューを作成して、場所ごとに使い分けられる

    デフォルトの制限

    標準機能だけでは、以下のような制限があります:

    • メニュー項目に説明文を追加しても表示されない
    • HTMLの構造が固定されていてデザインの自由度が低い
    • ショートコードで好きな場所に表示できない
    • CSSクラスを細かく指定できない

    これらの制限を解消するのが、今回紹介するカスタマイズです。

    カスタマイズの準備

    まず、テーマのfunctions.phpファイルに以下のコードを追加して、カスタムメニュー機能を有効化します。

    /* カスタムメニュー機能に対応させる */
    function mymenus_setup() {
      add_theme_support('menus');
    }
    add_action('after_setup_theme', 'mymenus_setup');
    

    このコードにより、管理画面に「メニュー」の設定項目が表示されるようになります。

    カスタマイズ例とコード解説

    1. メニュー内でショートコードを使えるようにする

    /* メニュー・テキストウィジェット内でショートコードを使えるようにする */
    add_filter('wp_nav_menu', 'do_shortcode');
    add_filter('widget_text', 'do_shortcode');
    

    できるようになること:

    • メニューのタイトルやリンクテキストにショートコードを記述できる
    • 動的なコンテンツをメニューに表示できる

    2. カスタムWalkerクラスで表示をカスタマイズ

    Walkerクラスは、メニューのHTML出力を制御する重要な仕組みです。

    class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
      function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
        // $argsを配列からオブジェクトに変換(PHP8対応)
        if (is_array($args)) {
          $args = (object) $args;
        }
    
        // 独自のCSSクラスを追加
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;
    
        if (isset($args->item_class)) {
          $classes[] = $args->item_class;
        }
    
        // クラス名を生成
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
        !empty($class_names) and $class_names = ' class="' . esc_attr($class_names) . '"';
    
        // リスト項目を出力
        $output .= "<li id='menu-item-$item->ID' $class_names>";
    
        // リンクの属性を設定
        $attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
        $attributes .= !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
        $attributes .= !empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : '';
        $attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : '';
        $attributes .= isset($args->link_class) ? ' class="' . esc_attr($args->link_class) . '"' : '';
    
        // ★重要: 説明文を表示する
        $description = !empty($item->description) ? '<span class="menu-description">' . esc_attr($item->description) . '</span>' : '';
    
        // 最終的なHTMLを組み立て
        $item_output = $args->before . "<a $attributes>"
          . $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $description
          . $args->link_after . '</a> '
          . $args->after;
    
        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
      }
    }
    

    このコードの重要ポイント:

    1. PHP8対応: $argsを配列からオブジェクトに変換することで、最新のPHPでもエラーが出ないようにしています
    2. カスタムクラスの追加: item_classlink_classを指定できるようになります
    3. 説明文の表示: メニュー項目の「説明」フィールドに入力した内容が表示されます

    3. ショートコードでメニューを呼び出せるようにする

    通常、メニューはテーマファイル内の決まった場所にしか表示できませんが、ショートコードを使えば投稿やウィジェットなど、どこにでも配置できます。

    パターン1: navタグで囲んだメニュー(cmenu)

    function custom_menu_nav($atts, $content = null) {
      extract(shortcode_atts(
        array(
          'menu' => '',
          'container' => 'nav',
          'container_class' => '',
          'menu_class' => 'menu',
          'item_class' => '',
          'link_class' => '',
          'walker' => new Custom_Walker_Nav_Menu(),
          // その他のオプション...
        ),
        $atts
      ));
      return wp_nav_menu(array(/* 設定 */));
    }
    add_shortcode("cmenu", "custom_menu_nav");
    

    使用例:

    [cmenu menu="メインメニュー" container_class="header-nav" menu_class="main-menu" link_class="nav-link"]
    

    パターン2: ulタグのみのメニュー(ulmenu)

    containerをfalseにすることで、余計なラッパーなしでulタグだけを出力します。

    使用例:

    [ulmenu menu="サイドバーメニュー" menu_class="sidebar-menu" item_class="sidebar-item"]
    

    パターン3: liタグのみのメニュー(limenu)

    containerもulタグも出力せず、liタグだけを表示します。

    使用例:

    [limenu menu="フッターメニュー" link_class="footer-link"]
    

    カスタマイズで実現できること

    1. デザインの自由度が大幅にアップ

    • 各メニュー項目に独自のCSSクラスを追加できる
    • リンクタグに直接クラスを指定できる
    • 説明文を使ってサブタイトルやアイコンを表示できる

    CSSの例:

    .menu-description {
      display: block;
      font-size: 0.8em;
      color: #666;
      margin-top: 3px;
    }
    
    .nav-link {
      padding: 10px 15px;
      transition: all 0.3s;
    }
    
    .nav-link:hover {
      background-color: #f0f0f0;
    }
    

    2. 柔軟なレイアウト配置

    ショートコードを使うことで:

    • 投稿本文の途中にメニューを挿入
    • ウィジェットエリアにメニューを配置
    • ページビルダーのブロック内にメニューを設置
    • 複数のメニューを同じページに表示

    3. メンテナンス性の向上

    • メニューの内容は管理画面から変更できる
    • コードを触らずにナビゲーションを更新可能
    • 複数のメニューを用途別に管理できる

    4. 実用的な使用例

    例1: メガメニューの実装

    [cmenu menu="メガメニュー" container_class="mega-menu-wrapper" item_class="mega-item" link_class="mega-link"]
    

    説明文にカテゴリー一覧やサムネイル画像のHTMLを入れることで、リッチなメガメニューを実現できます。

    例2: アイコン付きメニュー

    メニュー項目の「説明」フィールドにFont Awesomeのクラスを記述:

    <i class="fas fa-home"></i>
    

    これがメニュー項目と一緒に表示されます。

    例3: ランディングページ内ナビゲーション

    1ページ完結型のLPで、セクションごとのアンカーリンクメニューを作成:

    [ulmenu menu="LP用ナビ" menu_class="lp-nav" link_class="smooth-scroll"]
    

    まとめ

    WordPressのカスタムメニュー機能をカスタマイズすることで、以下が実現できます:

    • デザインの自由度向上: CSSクラスの細かい制御、説明文の表示
    • 配置の柔軟性: ショートコードでどこにでも設置可能
    • メンテナンス性: 管理画面から簡単に更新
    • 拡張性: メガメニューやアイコン付きメニューなど高度な表現

    今回紹介したコードをfunctions.phpに追加するだけで、これらの機能がすべて使えるようになります。ぜひあなたのサイトでも試してみてください!


    注意事項:

    • functions.phpを編集する前に、必ずバックアップを取りましょう
    • 子テーマを使用している場合は、子テーマのfunctions.phpに記述してください
    • コードをコピー&ペーストする際は、全角スペースが混入しないよう注意してください