「カテゴリー」ウィジェットでカスタムタクソノミーを表示する方法

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

はじめに

Gutenbergエディター

「カテゴリー一覧(ターム一覧)」ブロックはカスタムタクソノミーに対応しています(図1参照)。
一方、「カテゴリー」ウィジェットは標準ではカスタムタクソノミーを選択できず、通常のカテゴリーのみが対象となります。

また、カスタムタクソノミーはタグクラウド用のタクソノミーとして扱われるため、「タグクラウド」ウィジェットでは選択可能ですが、ドロップダウン表示には対応していません。

そこで、「カテゴリー」ブロックと同様に、カスタムタクソノミーも選択でき、さらにドロップダウン表示も可能とします。

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

完成イメージ

実装手順

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

// ウィジェットに設定メニューを追加
add_action('in_widget_form', function ($widget, $return, $instance) {
  if ($widget->id_base !== 'categories') {
    return;
  }

  // タクソノミー設定を取得
  $taxonomy = !empty($instance['taxonomy']) ? $instance['taxonomy'] : 'category';

  // 利用可能な公開タクソノミーを取得
  $taxonomies = get_taxonomies(['public' => true, 'show_ui' => true], 'names');

  ?>
  <p>
    <label>タクソノミー:</label><br>
    <select class="widefat" name="<?= esc_attr($widget->get_field_name('taxonomy')); ?>">
      <?php foreach ($taxonomies as $value): ?>
        <option value="<?= esc_attr($value); ?>" <?php selected($taxonomy, $value); ?>>
          <?= esc_html(get_taxonomy($value)->label); ?>
        </option>
      <?php endforeach; ?>
    </select>
  </p>
  <?php
}, 10, 3);


// ウィジェットの入力データを更新
add_filter('widget_update_callback', function ($instance, $new_instance, $old_instance, $widget) {
  if ($widget->id_base !== 'categories') {
    return $instance;
  }

  // タクソノミー設定なしは処理対象外
  if (empty($new_instance['taxonomy'])) {
    return $instance;
  }

  // 許可されたタクソノミーか確認
  $taxonomies = get_taxonomies(['public' => true, 'show_ui' => true], 'names');
  if (!in_array($new_instance['taxonomy'], $taxonomies, true)) {
    return $instance;
  }

  $instance['taxonomy'] = sanitize_text_field($new_instance['taxonomy']);

  return $instance;
}, 10, 4);


// カテゴリーのクエリを変更
add_filter('widget_categories_args', function ($args, $instance) {
  if (empty($instance['taxonomy'])) {
    $args['taxonomy'] = 'category';
    return $args;
  }

  // タクソノミーを設定
  $args['taxonomy'] = $instance['taxonomy'];

  return $args;
}, 10, 2);


// ドロップダウン形式のカテゴリー設定
add_filter('widget_categories_dropdown_args', function ($args, $instance) {
  // タクソノミーを取得
  $taxonomy = !empty($instance['taxonomy']) ? $instance['taxonomy'] : 'category';
  $args['taxonomy'] = $taxonomy;

  // ドロップダウン形式でない場合は処理対象外
  if (empty($instance['dropdown'])) {
    return $args;
  }

  // ドロップダウンの初期項目を設定
  $args['show_option_none'] = 'タクソノミーを選択';
  $args['option_none_value'] = '-1';

  // 独自ウォーカーを設定
  $args['walker'] = new class($taxonomy) extends Walker_CategoryDropdown {
    private $taxonomy;

    public function __construct($taxonomy) {
      $this->taxonomy = $taxonomy;
    }

    function start_el(&$output, $term, $depth = 0, $args = [], $id = 0) {
      // タームなしは処理対象外
      if (!$term) {
        return;
      }

      // タームのリンクを取得
      $term_link = get_term_link($term, $this->taxonomy);
      if (is_wp_error($term_link)) {
        return;
      }

      // 現在のタームを取得
      $current_term = get_queried_object();
      $selected = '';

      // 現在のタームを選択状態に設定
      if (!$current_term || !($current_term instanceof WP_Term)) {
        // ターム情報なしは処理対象外
      } elseif ($current_term->term_id === $term->term_id && $current_term->taxonomy === $this->taxonomy) {
        $selected = ' selected="selected"';
      }

      $pad = str_repeat('&nbsp;', $depth * 3);
      $output .= '<option class="level-' . $depth . '" value="' . esc_url($term_link) . '"' . $selected . '>'
                . $pad . esc_html($term->name);

      // 投稿数を設定
      if (!empty($args['show_count'])) {
        $output .= ' (' . number_format_i18n($term->count) . ')';
      }
      $output .= "</option>\n";
    }
  };

  return $args;
}, 10, 2);


// フロント用JS・CSSを追加
add_action('wp_enqueue_scripts', function () {
  ob_start();
  ?>
  document.querySelectorAll('.widget_categories select').forEach(select => {
    select.addEventListener('change', () => {
      if (!select.value || select.value === '-1') {
        return;
      }

      // 選択されたURLへ遷移
      location.href = select.value;
    });
  });
  <?php
  wp_add_inline_script('jquery', ob_get_clean());
});

「カテゴリー一覧(ターム一覧)」ブロックを使用する方法

「カテゴリー一覧(ターム一覧)」ブロックのコードを「ブロック」ウィジェットに入力すれば、カスタムタクソノミーも表示できます。
ノーコードで実現可能ですが、WordPress標準の表示となるため、Cocoonのデザインとは異なり、調整が必要です。

さいごに

今回紹介した方法を使えば、「カテゴリー」ウィジェットでカスタム投稿タイプを簡単に表示できるようになります。
標準では対応していないため、複数の投稿タイプを運用しているサイトでは非常に便利です。
ウィジェットに投稿タイプ選択を追加することで、投稿ごとにカテゴリーを切り替えて表示でき、サイト訪問者にとっても見やすいカテゴリーページを提供できます。

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