グローバルナビメニューのカテゴリーに投稿数を表示する方法

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

拡張:メニュー単位で件数表示を切り替える

前述の実装では、対象となるすべてのナビメニューやウィジェットに、一律で投稿数が表示されていました。

しかし、メニューごとに表示・非表示を切り替えたい場合もあります。

そこで、外観→メニューの管理画面にチェックボックスを追加し、メニュー単位で投稿数の表示をオン・オフできるようにします。

完成イメージ

実装手順

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

// 管理画面用JS・CSSを追加
add_action('admin_enqueue_scripts', function ($hook) {
  if ($hook !== 'nav-menus.php') {
    return;
  }

  global $nav_menu_selected_id;

  // 編集中のメニューIDを取得
  $menu_id = (int) $nav_menu_selected_id;

  // カテゴリー件数の表示設定を取得
  $enabled = get_term_meta($menu_id, 'show_category_count', true) === '1';

  ob_start();
  ?>
  jQuery(function($) {
    const checkbox = '<p class="field-custom-count description description-wide"><label><input type="checkbox" name="show_category_count" value="1" <?php echo $enabled ? 'checked' : ''; ?>> カテゴリーの投稿件数を表示</label></p>';
    $('.menu-settings .menu-settings-group').eq(0).append(checkbox);
  });
  <?php
  wp_add_inline_script('jquery', ob_get_clean());
});


// メニュー項目を保存
add_action('wp_update_nav_menu', function ($menu_id) {
  // 権限チェック
  if (!current_user_can('edit_theme_options')) {
    return;
  }

  if (isset($_POST['show_category_count']) && $_POST['show_category_count'] === '1') {
    update_term_meta($menu_id, 'show_category_count', '1');
  } else {
    delete_term_meta($menu_id, 'show_category_count');
  }

});


/**
 * メニューのカテゴリー件数表示設定を取得
 *
 * @param int $menu_id メニューID
 * @return bool 表示設定
 */
if (!function_exists('my_should_show_category_count')):
function my_should_show_category_count($menu_id) {
  return get_term_meta($menu_id, 'show_category_count', true) === '1';
}
endif;


/**
 * カテゴリーメニュー項目に投稿件数を追加
 *
 * @param array $items メニュー項目
 * @return array 投稿件数を追加したメニュー項目
 */
if (!function_exists('my_append_category_count')):
function my_append_category_count($items) {
  foreach ($items as $item) {
    // カテゴリー以外のメニュー項目は処理対象外
    if ($item->type !== 'taxonomy' || $item->object !== 'category') {
      continue;
    }

    // カテゴリー情報を取得
    $category = get_category($item->object_id);

    // カテゴリー情報が取得できない場合は処理対象外
    if (!$category || is_wp_error($category)) {
      continue;
    }

    // メニュー項目のタイトルに投稿件数を追加
    $item->title .= sprintf(' (%d)', $category->count);
  }

  return $items;
}
endif;


// 通常のメニュー表示にカテゴリー件数を追加
add_filter('wp_nav_menu_objects', function ($items, $args) {
  // 対象とするメニュー位置を設定
  $target_locations = [
    'navi-header',
    'navi-mobile',
    'navi-header-mobile',
    'navi-footer',
    'navi-footer-mobile',
    'navi-mobile-slide-in',
  ];

  // 対象外のメニュー位置は処理対象外
  if (empty($args->theme_location) || !in_array($args->theme_location, $target_locations, true)) {
    return $items;
  }

  // メニュー位置に割り当てられたメニューIDを取得
  $locations = get_nav_menu_locations();
  $menu_id = $locations[$args->theme_location] ?? 0;

  // メニューIDがない場合、または表示設定が無効な場合は処理対象外
  if (!$menu_id || !my_should_show_category_count($menu_id)) {
    return $items;
  }

  // カテゴリーメニュー項目に投稿件数を追加
  return my_append_category_count($items);
}, 10, 2);


// ウィジェット・ショートコードのメニュー表示にカテゴリー件数を追加
add_filter('wp_get_nav_menu_items', function ($items, $menu, $args) {
  // メニュー項目が空、または配列以外の場合は処理対象外
  if (empty($items) || !is_array($items)) {
    return $items;
  }

  // 呼び出し元の関数を取得
  $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

  // 対象とする関数を設定
  $target_functions = [
    'get_box_menu_tag',
    'get_navi_card_list_tag',
  ];

  $is_target = false;

  // 呼び出し元に対象関数が含まれるか確認
  foreach ($trace as $frame) {
    if (isset($frame['function']) && in_array($frame['function'], $target_functions, true)) {
      $is_target = true;
      break;
    }
  }

  // 対象関数から呼び出されていない場合は処理対象外
  if (!$is_target) {
    return $items;
  }

  // メニュー情報を取得
  $menu_object = wp_get_nav_menu_object($menu);

  // メニュー情報が取得できない場合は処理対象外
  if (!$menu_object || is_wp_error($menu_object)) {
    return $items;
  }

  // カテゴリー件数の表示設定が無効な場合は処理対象外
  if (!my_should_show_category_count($menu_object->term_id)) {
    return $items;
  }

  // カテゴリーメニュー項目に投稿件数を追加
  return my_append_category_count($items);
}, 10, 3);

さいごに

今回紹介した方法を使えば、グローバルナビメニューにカテゴリーごとの投稿数を簡単に表示できます。
これにより、ユーザーは各カテゴリーの活性度を一目で把握でき、ナビゲーションがより便利になるでしょう。

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