はじめに
WordPressでは、カテゴリーウィジェットを利用して、カテゴリーの一覧をサイドバーなどに表示できます。
しかし、カテゴリーが増えてくると、表示する必要のないカテゴリーが一覧に含まれ、目的のカテゴリーを見つけにくくなることがあります。
そこで、機能を拡張し、カテゴリー一覧画面に「表示/非表示」の切り替えボタンを設置して、カテゴリーごとに表示・非表示を設定できるようにします。
また、親カテゴリーを非表示にした場合は、子カテゴリーも自動的に非表示にすることで、カテゴリー一覧を整理しやすくします。
この記事では、この方法について説明します。
完成イメージ

実装手順
以下のコードをfunctions.phpに追加します。
/**
* 非表示カテゴリーとその子孫カテゴリーのID一覧を取得
*
* @return int[] 非表示対象となるカテゴリーIDの配列
*/
if (!function_exists('my_get_hidden_category_cloud_ids')):
function my_get_hidden_category_cloud_ids() {
// 非表示フラグが設定されたカテゴリーIDを取得
$hidden_terms = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'meta_query' => [
[
'key' => 'my_hide_category_cloud',
'value' => '1',
'compare' => '=',
],
],
'fields' => 'ids',
]);
// 非表示カテゴリーが存在しない場合は空の配列を返して終了
if (is_wp_error($hidden_terms) || empty($hidden_terms)) {
return [];
}
$exclude_ids = [];
foreach ($hidden_terms as $term_id) {
// 非表示カテゴリー自身のIDを登録
$exclude_ids[] = (int) $term_id;
// 子孫カテゴリーのIDを取得
$children = get_term_children((int) $term_id, 'category');
// 子孫カテゴリーが存在する場合は除外対象に追加
if (!is_wp_error($children) && !empty($children)) {
$exclude_ids = array_merge($exclude_ids, array_map('intval', $children));
}
}
// 重複するカテゴリーIDを除去して返却
return array_values(array_unique($exclude_ids));
}
endif;
// 管理画面一覧にカラムを追加
add_filter('manage_edit-category_columns', function ($columns) {
$columns['category_visibility'] = '表示/非表示';
return $columns;
});
// 管理画面一覧のカラムにデータを表示
add_filter('manage_category_custom_column', function ($value, $column_name, $term_id) {
if ('category_visibility' !== $column_name) {
return $value;
}
// 非表示カテゴリーとその子孫のIDを取得
$hidden_ids = my_get_hidden_category_cloud_ids();
// 対象カテゴリーの非表示状態を判定
$is_hidden = in_array((int) $term_id, $hidden_ids, true);
// 非表示状態に応じてCSSクラスを設定
$btn_class = $is_hidden ? 'category-vis-btn is-hidden' : 'category-vis-btn is-visible';
$btn_text = $is_hidden ? '非表示' : '表示中';
return '<button type="button" class="button button-small ' . esc_attr($btn_class) . '" data-term-id="' . esc_attr($term_id) . '">' . esc_html($btn_text) . '</button>';
}, 10, 3);
// 管理画面用JS・CSSを追加
add_action('admin_enqueue_scripts', function ($hook_suffix) {
if ($hook_suffix !== 'edit-tags.php') {
return;
}
// 現在の管理画面のスクリーン情報を取得
$screen = get_current_screen();
if (!$screen || $screen->taxonomy !== 'category') {
return;
}
ob_start();
?>
.category-vis-btn {
&.is-visible {
border-color: #00a32a !important;
color: #00a32a !important;
}
&.is-hidden {
border-color: #d63638 !important;
color: #d63638 !important;
}
}
<?php
wp_add_inline_style('wp-admin', ob_get_clean());
$handle = 'category-visibility-admin-js';
wp_register_script($handle, '');
wp_enqueue_script($handle);
wp_localize_script($handle, 'categoryVisData', [
'ajaxurl' => admin_url('admin-ajax.php'),
'category_visibility_nonce' => wp_create_nonce('category_visibility_action')
]);
ob_start();
?>
jQuery(document).ready(function($) {
$(document).on('click', '.category-vis-btn', function() {
var $btn = $(this);
var termId = $btn.data('term-id');
$btn.prop('disabled', true);
$.ajax({
url: categoryVisData.ajaxurl,
type: 'POST',
data: {
action: 'toggle_category_visibility_btn',
term_id: termId,
category_visibility_nonce: categoryVisData.category_visibility_nonce
},
success: function(response) {
$btn.prop('disabled', false);
if (response.success) {
window.location.reload();
} else {
alert(response.data || '更新に失敗しました。');
}
},
error: function() {
$btn.prop('disabled', false);
alert('通信エラーが発生しました。');
}
});
});
});
<?php
wp_add_inline_script($handle, ob_get_clean());
});
// Ajaxアクションを追加
add_action('wp_ajax_toggle_category_visibility_btn', function () {
if (!isset($_POST['term_id'], $_POST['category_visibility_nonce'])) {
wp_send_json_error('不正なリクエストです。');
}
// nonceチェック
if (!wp_verify_nonce($_POST['category_visibility_nonce'], 'category_visibility_action')) {
wp_send_json_error('セキュリティチェックに失敗しました。');
}
// 権限チェック
if (!current_user_can('manage_categories')) {
wp_send_json_error('権限がありません。');
}
// リクエストからカテゴリーIDを取得
$term_id = absint($_POST['term_id']);
// 対象カテゴリーの情報を取得
$term = get_term($term_id, 'category');
if (!$term || is_wp_error($term)) {
wp_send_json_error('カテゴリーが見つかりません。');
}
// 現在の非表示フラグを取得
$current_hidden = get_term_meta($term_id, 'my_hide_category_cloud', true);
if ($current_hidden === '1') {
delete_term_meta($term_id, 'my_hide_category_cloud');
$new_hidden = '';
} else {
update_term_meta($term_id, 'my_hide_category_cloud', '1');
$new_hidden = '1';
}
wp_send_json_success(['is_hidden' => $new_hidden]);
});
/**
* カテゴリーウィジェットのクエリから非表示カテゴリーを除外
*
* @param array $args カテゴリーウィジェットのクエリ設定
* @return array 非表示カテゴリーを除外したクエリ設定
*/
if (!function_exists('my_exclude_hidden_category_cloud_ids')):
function my_exclude_hidden_category_cloud_ids($args) {
// 非表示カテゴリーとその子孫のIDを取得
$hidden_ids = my_get_hidden_category_cloud_ids();
// 除外対象がない場合は元の設定を返して終了
if (empty($hidden_ids)) {
return $args;
}
// 既存の除外カテゴリーIDを取得
$existing_ids = isset($args['exclude'])
? wp_parse_id_list($args['exclude'])
: [];
// 既存の除外設定に非表示カテゴリーのIDを追加して置換
$args['exclude'] = implode(',', array_unique(array_merge($existing_ids, $hidden_ids)));
return $args;
}
endif;
// カテゴリーのクエリを変更
add_filter('widget_categories_args', 'my_exclude_hidden_category_cloud_ids');
add_filter('widget_categories_dropdown_args', 'my_exclude_hidden_category_cloud_ids');
さいごに
今回紹介した方法を使えば、不要なカテゴリーを非表示にして、WordPressのカテゴリー一覧を思い通りにコントロールできるようになります。
管理画面のカテゴリー一覧からワンクリックで表示・非表示を切り替えられるため、運用の手間もかかりません。
カテゴリーが増えて一覧が見づらくなっている方や、親子関係を維持しながら表示するカテゴリーを整理したい方は、ぜひ導入してみてください。
