グローバルナビメニューをカテゴリーページごとに変更する方法

Cocoonカスタマイズ集
この記事は約8分で読めます。
記事内に広告が含まれています。

実装手順

以下の手順で実装します。

  • ラベル
    メニューの作成
    メニュー

    外観→メニューからカテゴリーごとに表示するメニューを作成します(図1参照)。
    図1①のメニューの位置を、表1に示します。

    メニューの位置
    メニューの位置値
    ヘッダーメニューNAV_MENU_HEADER
    ヘッダーモバイルメニューNAV_MENU_HEADER_MOBILE
    ヘッダーモバイルボタンNAV_MENU_HEADER_MOBILE_BUTTONS
    フッターメニューNAV_MENU_FOOTER
    フッターモバイルボタンNAV_MENU_FOOTER_MOBILE_BUTTONS
    モバイルスライドインメニューNAV_MENU_MOBILE_SLIDE_IN
  • ラベル
    PHPを追加

    以下のコードをfunctions.phpに追加します。
    例えば、カテゴリーID=123の場合、図1②で設定したメニュー名「menu123」に変更します。

    add_filter('wp_nav_menu_args', function ($args) {
      // カテゴリーIDと対応するメニュー名の配列
      $cat_menu_map = [
        123 => 'menu123',
        456 => 'menu456'
      ];
    
      // ヘッダーメニューの場合
      if ($args["theme_location"] === NAV_MENU_HEADER) {
        if (is_category()) {
          // 現在のカテゴリーIDを取得
          $cat_id = get_queried_object_id();
    
         // マップ内にカテゴリーIDが存在する場合
         if (isset($cat_menu_map[$cat_id])) {
            $args['menu'] = $cat_menu_map[$cat_id];
          }
        }
      }
    
      return $args;
    });

拡張:カテゴリー編集に独自項目を追加する方法

投稿→カテゴリー→カテゴリー編集に、独自にの設定項目「ヘッダーメニュー」を追加します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// カテゴリー編集にメニューを追加
add_action('category_edit_form_fields', function ($term) {
  // ナビゲーションメニュー一覧を取得
  $menus = wp_get_nav_menus();

  // 保存済みメニューIDを取得
  $menu_id = get_term_meta($term->term_id, 'my_category_navi_header', true);

  ?>
  <tr class="form-field category-navi-header">
    <th>
      <label for="category-navi-header">ヘッダーメニュー</label>
    </th>
    <td>
      <?php wp_nonce_field('category_navi_header_action', 'category_navi_header_nonce'); ?>
      <select name="my_category_navi_header" id="category-navi-header">
        <option value="">未選択</option>
        <?php foreach ($menus as $menu) : ?>
          <option value="<?= esc_attr($menu->term_id); ?>" <?php selected($menu_id, $menu->term_id); ?>><?= esc_html($menu->name); ?></option>
        <?php endforeach; ?>
      </select>

      <p class="description">このカテゴリーに表示するヘッダーメニューを選択してください。</p>
    </td>
  </tr>
  <?php
});


// カテゴリー編集の設定を保存
add_action('edited_category', function ($term_id) {
  // nonceチェック
  if (!isset($_POST['category_navi_header_nonce']) || !wp_verify_nonce($_POST['category_navi_header_nonce'], 'category_navi_header_action')) {
    return;
  }

  if (isset($_POST['my_category_navi_header'])) {
    update_term_meta($term_id, 'my_category_navi_header', (int) $_POST['my_category_navi_header']);
  }
});


// ヘッダーメニューを変更
add_filter('wp_nav_menu_args', function ($args) {
  if (empty($args['theme_location']) || $args['theme_location'] !== 'navi-header') {
    return $args;
  }

  if (!is_category()) {
    return $args;
  }

  $cat    = get_queried_object();
  $cat_id = $cat->term_id;

  // カテゴリーに保存されたメニューIDを取得
  $menu_id = get_term_meta($cat_id, 'my_category_navi_header', true);

  // メニューを変更
  if (!empty($menu_id) && is_nav_menu((int) $menu_id)) {
    $args['menu'] = (int) $menu_id;
  }

  return $args;
});

参考:カテゴリー、メニュー情報を表示する方法

管理画面のダッシュボードに、現在使用可能な「カテゴリー」と「ナビゲーションメニュー」を一覧表示します。

完成イメージ

実装コード

以下のコードをfunctions.phpに追加します。

// ダッシュボードウィジェットを追加
add_action('wp_dashboard_setup', function () {
  wp_add_dashboard_widget(
    'category-and-menu-list',
    'カテゴリー・メニュー一覧',
    'render_category_and_menu_list'
  );
});


/**
 * ダッシュボードにウィジェットを出力
 *
 * @return void
 */
if (!function_exists('render_category_and_menu_list')):
function render_category_and_menu_list() {
  // カテゴリーを取得
  $categories = get_categories([
    'hide_empty' => false,
  ]);

  // ナビゲーションメニュー一覧を取得
  $menus = wp_get_nav_menus();

  if (empty($categories) && empty($menus)) {
    return;
  }

  ?>
  <div class="category-and-menu-list">
    <?php if (!empty($categories)): ?>
      <h3 class="category-and-menu-list__heading">カテゴリー一覧</h3>
      <table class="category-and-menu-list__table widefat fixed striped">
        <thead>
          <tr>
            <th>カテゴリー名</th>
            <th>ID</th>
          </tr>
        </thead>
        <tbody>
          <?php foreach ($categories as $cat): ?>
            <tr>
              <td><?= esc_html($cat->name); ?></td>
              <td><?= esc_html($cat->term_id); ?></td>
            </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    <?php endif; ?>

    <?php if (!empty($menus)): ?>
      <h4 class="category-and-menu-list__heading">メニュー一覧</h4>
      <table class="category-and-menu-list__table widefat fixed striped">
        <thead>
          <tr>
            <th>メニュー名</th>
            <th>ID</th>
          </tr>
        </thead>
        <tbody>
          <?php foreach ($menus as $menu): ?>
            <tr>
              <td><?= esc_html($menu->name); ?></td>
              <td><?= esc_html($menu->term_id); ?></td>
            </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    <?php endif; ?>
  </div>
  <?php
}
endif;

さいごに

今回紹介した方法を使えば、カテゴリーごとにグローバルナビメニューを柔軟に変更できます。
表1に示したようにメニューの位置を指定すれば、他のメニューにも応用が可能です。
また、is_category()をis_page()に変更することで、特定の固定ページにも対応できるため、さらに汎用性の高いカスタマイズが実現できます。

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