「カテゴリーで絞り込んでから一括編集したいのに、できない…」
WordPressのカテゴリーのドロップダウンで絞り込んだ状態では、一括操作でカテゴリーを変更できないという制限があります。これはWordPressの仕様なのですが、代わりにカラムヘッダーをクリックしてソートできるようにすれば、同じカテゴリーの記事をまとめて選択→一括編集が可能になります。
この記事では、
- 固定ページにもカテゴリー・タグを追加
- カテゴリー管理画面にID列を追加
- 投稿ページ・固定ページ一覧で「カテゴリー」「投稿者」「タグ」のカラムをクリックしてソート
functions.phpに追加するだけで使える実践的なカスタマイズコードを紹介します。
完成イメージ

カスタマイズ後は、投稿一覧・固定ページ一覧で「カテゴリー」「投稿者」「タグ」のヘッダーをクリックすると、昇順・降順でソートできるようになります。
これにより、同じカテゴリーの記事がまとまって表示されるので、チェックボックスで選択→一括操作でカテゴリー変更、といった作業が効率的に行えます。
実装コード(functions.php)
以下のコードをテーマのfunctions.phpに追加してください。子テーマを使用している場合は、子テーマのfunctions.phpに追加することをおすすめします。
<?php
/**
* WordPress管理画面カスタマイズ
* - 投稿・固定ページ一覧のソート機能追加
* - 固定ページへのカテゴリー・タグ追加
* - カテゴリー一覧へのID列追加
*/
/* ■カテゴリー・タグ設定
====================================== */
/* 固定ページにカテゴリーとタグを追加 */
function add_taxonomy_to_pages() {
register_taxonomy_for_object_type('category', 'page');
register_taxonomy_for_object_type('post_tag', 'page');
}
add_action('init', 'add_taxonomy_to_pages');
/* カテゴリー・タグアーカイブに固定ページを含める */
function add_page_to_archive($query) {
if (!is_admin() && $query->is_main_query()) {
if ($query->is_category() || $query->is_tag()) {
$query->set('post_type', array('post', 'page'));
}
}
}
add_action('pre_get_posts', 'add_page_to_archive');
/* カテゴリー一覧に「ID」列を追加 */
function add_category_columns_id($columns) {
$columns['category_id'] = 'ID';
return $columns;
}
add_filter('manage_edit-category_columns', 'add_category_columns_id');
/* ID列にデータを表示 */
function show_category_id_column($content, $column_name, $term_id) {
if ($column_name === 'category_id') {
return $term_id;
}
return $content;
}
add_filter('manage_category_custom_column', 'show_category_id_column', 10, 3);
/* ID列をソート可能にする */
function make_category_id_sortable($columns) {
$columns['category_id'] = 'term_id';
return $columns;
}
add_filter('manage_edit-category_sortable_columns', 'make_category_id_sortable');
/* ■投稿・固定ページ一覧のソート機能追加
====================================== */
/* 投稿一覧のカラムをソート可能にする(カテゴリー・投稿者・タグ) */
function make_post_columns_sortable($columns) {
$columns['categories'] = 'category_name';
$columns['author'] = 'author';
$columns['tags'] = 'tag_name';
return $columns;
}
add_filter('manage_edit-post_sortable_columns', 'make_post_columns_sortable');
/* 固定ページ一覧のカラムをソート可能にする(カテゴリー・投稿者・タグ) */
function make_page_columns_sortable($columns) {
$columns['categories'] = 'category_name';
$columns['author'] = 'author';
$columns['tags'] = 'tag_name';
return $columns;
}
add_filter('manage_edit-page_sortable_columns', 'make_page_columns_sortable');
/* 固定ページ一覧にカテゴリー・タグカラムを追加 */
function add_taxonomy_columns_to_pages($columns) {
//authorの後ろにカテゴリーとタグを追加
$new_columns = array();
foreach ($columns as $key => $value) {
$new_columns[$key] = $value;
if ($key === 'author') {
$new_columns['categories'] = 'カテゴリー';
$new_columns['tags'] = 'タグ';
}
}
return $new_columns;
}
add_filter('manage_pages_columns', 'add_taxonomy_columns_to_pages');
/* 固定ページ一覧のカテゴリー・タグカラムにデータを表示 */
function show_taxonomy_columns_on_pages($column_name, $post_id) {
if ($column_name === 'categories') {
$categories = get_the_category($post_id);
if (!empty($categories)) {
$cat_links = array();
foreach ($categories as $cat) {
$cat_links[] = '<a href="' . esc_url(admin_url('edit.php?post_type=page&category_name=' . $cat->slug)) . '">' . esc_html($cat->name) . '</a>';
}
echo implode(', ', $cat_links);
} else {
echo '—';
}
}
if ($column_name === 'tags') {
$tags = get_the_tags($post_id);
if (!empty($tags)) {
$tag_links = array();
foreach ($tags as $tag) {
$tag_links[] = '<a href="' . esc_url(admin_url('edit.php?post_type=page&tag=' . $tag->slug)) . '">' . esc_html($tag->name) . '</a>';
}
echo implode(', ', $tag_links);
} else {
echo '—';
}
}
}
add_action('manage_pages_custom_column', 'show_taxonomy_columns_on_pages', 10, 2);
/* カテゴリー・タグでのソート処理(投稿・固定ページ共通) */
function sort_posts_by_taxonomy($query) {
if (!is_admin() || !$query->is_main_query()) {
return;
}
$screen = get_current_screen();
if (!$screen || !in_array($screen->id, array('edit-post', 'edit-page'), true)) {
return;
}
$orderby = $query->get('orderby');
//カテゴリーでソート
if ($orderby === 'category_name') {
add_filter('posts_clauses', 'sort_by_category_clauses');
}
//タグでソート
if ($orderby === 'tag_name') {
add_filter('posts_clauses', 'sort_by_tag_clauses');
}
}
add_action('pre_get_posts', 'sort_posts_by_taxonomy');
/* カテゴリーでソートするためのSQL句を追加 */
function sort_by_category_clauses($clauses) {
global $wpdb;
$clauses['join'] .= " LEFT JOIN (
SELECT object_id, GROUP_CONCAT(t.name ORDER BY t.name ASC SEPARATOR ', ') as category_names
FROM {$wpdb->term_relationships} tr
INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'category'
INNER JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
GROUP BY object_id
) as cat_sort ON {$wpdb->posts}.ID = cat_sort.object_id";
$order = strtoupper(get_query_var('order')) === 'ASC' ? 'ASC' : 'DESC';
$clauses['orderby'] = "COALESCE(cat_sort.category_names, '') {$order}, " . $clauses['orderby'];
//フィルターを1回だけ実行
remove_filter('posts_clauses', 'sort_by_category_clauses');
return $clauses;
}
/* タグでソートするためのSQL句を追加 */
function sort_by_tag_clauses($clauses) {
global $wpdb;
$clauses['join'] .= " LEFT JOIN (
SELECT object_id, GROUP_CONCAT(t.name ORDER BY t.name ASC SEPARATOR ', ') as tag_names
FROM {$wpdb->term_relationships} tr
INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'post_tag'
INNER JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
GROUP BY object_id
) as tag_sort ON {$wpdb->posts}.ID = tag_sort.object_id";
$order = strtoupper(get_query_var('order')) === 'ASC' ? 'ASC' : 'DESC';
$clauses['orderby'] = "COALESCE(tag_sort.tag_names, '') {$order}, " . $clauses['orderby'];
//フィルターを1回だけ実行
remove_filter('posts_clauses', 'sort_by_tag_clauses');
return $clauses;
}
/* カテゴリー管理画面用のCSS */
function admin_custom_styles() {
$screen = get_current_screen();
if ($screen && $screen->id === 'edit-category') {
echo '<style>
.fixed .column-posts { width: 94px; }
.manage-column.column-category_id { width: 54px; }
</style>';
}
}
add_action('admin_head', 'admin_custom_styles');
コードの解説
1. 固定ページにカテゴリー・タグを追加
register_taxonomy_for_object_type()を使って、固定ページ(page)にカテゴリーとタグを関連付けています。
register_taxonomy_for_object_type('category', 'page');
register_taxonomy_for_object_type('post_tag', 'page');
これだけで固定ページの編集画面にカテゴリー・タグの選択UIが表示されるようになります。
2. ソート可能カラムの登録
manage_edit-{post_type}_sortable_columnsフィルターを使って、ソート可能なカラムを追加しています。
$columns['categories'] = 'category_name'; // カテゴリーカラム
$columns['author'] = 'author'; // 投稿者カラム
$columns['tags'] = 'tag_name'; // タグカラム
配列のキーがカラム名、値がソート時に使用するorderbyパラメータです。
3. カテゴリー・タグのソート処理
WordPressの標準機能では、カテゴリーやタグでのソートはサポートされていません。そのため、posts_clausesフィルターを使ってSQLクエリを直接カスタマイズしています。
ポイントはGROUP_CONCATを使っている点です。1つの投稿に複数のカテゴリー・タグが設定されている場合、それらをカンマ区切りで連結した文字列としてソートします。
GROUP_CONCAT(t.name ORDER BY t.name ASC SEPARATOR ', ')
例えば、「API, PHP, WordPress」という3つのタグが付いた記事は、「API, PHP, WordPress」という文字列としてソートされます。
カスタム投稿タイプに対応させるには
カスタム投稿タイプ(例:product)にも同じ機能を追加したい場合は、以下のように変更してください。
// ソート可能カラムの登録を追加
add_filter('manage_edit-product_sortable_columns', 'make_post_columns_sortable');
// ソート処理の対象画面を追加
if (!$screen || !in_array($screen->id, array('edit-post', 'edit-page', 'edit-product'), true)) {
return;
}
まとめ
WordPressの管理画面は、少しのカスタマイズで大幅に使いやすくなります。特に記事数が増えてくると、カテゴリーやタグでのソート機能は作業効率に直結します。
カテゴリーの絞り込みドロップダウンでは一括編集ができないという制限も、ソート機能があればカバーできます。ぜひ活用してみてください。

