メニューから除外カテゴリーや非公開ページを非表示にする方法

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

はじめに

Cocoon設定

表示したくないカテゴリーはCocoon設定→インデックス→「除外カテゴリー」として指定できます(図1参照)。
しかし、除外したカテゴリーはグローバルナビメニューなどに引き続き表示されてしまいます。

カテゴリーページ

メニューをクリックするとカテゴリーページが表示されますが、中身がないため「投稿は見つかりませんでした。」と表示されます(図2参照)。

メニュー

また、投稿や固定ページをあとから非公開に設定しても、メニュー上には引き続き表示されます(図3参照)。
そのため、該当の投稿や固定ページをメニューからクリックすると、「404エラー」 が表示されてしまいます。

そこで、非公開に設定された投稿や固定ページは、ログインしていないユーザーにはメニューに表示されないようにします。

同様に、除外カテゴリーに属する投稿も、メニューから非表示に設定します。

この記事では、この方法について説明します。

実装手順

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

add_filter('wp_get_nav_menu_items', function ($items, $menu, $args) {
  if (is_admin()) {
    return $items;
  }

  // 除外カテゴリーを取得
  $exclude_category_ids = get_archive_exclude_category_ids();
  if (!empty($exclude_category_ids)) {
    $exclude_category_ids = array_map('intval', $exclude_category_ids);
  }

  $is_logged_in = is_user_logged_in();

  foreach ($items as $key => $item) {
    // 除外カテゴリーは削除
    if (!empty($exclude_category_ids) && $item->type === 'taxonomy' && $item->object === 'category') {
      if (in_array((int) $item->object_id, $exclude_category_ids, true)) {
        unset($items[$key]);
        continue;
      }
    }

    // 非ログイン時の非公開項目は削除
    if (!$is_logged_in && $item->type === 'post_type') {
      $post = get_post($item->object_id);
      if (!$post || $post->post_status !== 'publish') {
        unset($items[$key]);
        continue;
      }
    }
  }

  return array_values($items);
}, 10, 3);

拡張:設定画面のメニュー項目から除外カテゴリーを非表示する方法

除外カテゴリーを設定しても、外観→メニューの「カテゴリー」一覧には表示されたままになります。
また、非公開ページと同様に、あとから除外に指定した場合もメニューには引き続き表示されます。

そこで、除外カテゴリーに該当する場合は、メニュー項目を非表示にし、タイトルに「除外」と付けて区別できるようにします。

完成イメージ

実装手順

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

// タームのクエリを変更
add_filter('get_terms_args', function ($args, $taxonomies) {
  global $pagenow;

  // 対象外は終了
  if ($pagenow !== 'nav-menus.php' || !in_array('category', $taxonomies, true)) {
    return $args;
  }

  // 除外カテゴリーを取得
  $exclude_category_ids = get_archive_exclude_category_ids();

  if (empty($exclude_category_ids)) {
    return $args;
  }

  $exclude_category_ids = array_map('intval', $exclude_category_ids);

  $args['exclude'] = $exclude_category_ids;

  return $args;
}, 10, 2);


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

  // 除外カテゴリーを取得
  $exclude_category_ids = get_archive_exclude_category_ids();

  if (!is_array($exclude_category_ids)) {
    $exclude_category_ids = explode(',', $exclude_category_ids);
  }

  $exclude_category_ids = array_map('intval', array_filter($exclude_category_ids, 'strlen'));
  $json = wp_json_encode($exclude_category_ids);

  // メニュー名に除外表示を設定
  ob_start();
  ?>
  jQuery(function ($) {
    var excludedIds = <?= $json; ?>;
    $('.menu-item').each(function() {
      var object = $('input[name^="menu-item-object["]', this);
      var input  = $('input[name^="menu-item-object-id"]', this);
      var type   = $('.item-type', this);

      // 除外カテゴリーを判定
      if (object.val() === 'category' && $.inArray(parseInt(input.val(), 10), excludedIds) !== -1) {
        type.text('除外:' + type.text());
      }
    });
  });
  <?php
  wp_add_inline_script('jquery', ob_get_clean());
});

さいごに

今回紹介した方法を使えば、グローバルナビメニューなどに不要なカテゴリーや非公開の投稿・固定ページが表示される問題を防げます。
閲覧ユーザーにとって不要なリンクを排除することで、サイトのナビゲーションをよりシンプルで分かりやすく保つことができます。

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