WordPressでは、管理画面の投稿一覧でタイトルや公開日などのカラムはクリックで並び替えができますが、カスタムフィールド(例:価格や優先度など)の値で並び替えるにはカスタマイズが必要です。本記事では、ACFやmeta boxなどで登録されたカスタムフィールドを、管理画面の投稿一覧でソート可能にする方法を解説します。
カスタムフィールドのカラムを管理画面に追加する
まずは投稿一覧にカスタムフィールドの列(カラム)を追加します。以下は「価格(price)」というカスタムフィールドを表示する例です。
functions.php:カラムの追加と表示
// カラムを追加
function add_price_column($columns) {
$columns['price'] = '価格';
return $columns;
}
add_filter('manage_post_posts_columns', 'add_price_column');
// カラムの内容を表示
function show_price_column($column_name, $post_id) {
if ($column_name === 'price') {
$price = get_post_meta($post_id, 'price', true);
echo esc_html($price);
}
}
add_action('manage_post_posts_custom_column', 'show_price_column', 10, 2);
カスタムフィールドでソート可能にする
次に、先ほど追加した「価格」カラムをソート可能にします。以下のように設定します。
functions.php:ソート可能化とクエリ調整
// ソート可能なカラムを追加
function make_price_column_sortable($columns) {
$columns['price'] = 'price';
return $columns;
}
add_filter('manage_edit-post_sortable_columns', 'make_price_column_sortable');
// ソート時のクエリを調整(priceが未設定の投稿も一覧から除外しない)
function sort_posts_by_price($query) {
if (!is_admin() || !$query->is_main_query()) return;
if ($query->get('orderby') === 'price') {
$order = $query->get('order') ?: 'ASC';
// 名前付きmeta_queryクラス(price_clause)を使うことで、
// トップレベルのmeta_key指定によるINNER JOIN(未設定投稿の除外)を回避する
$query->set('meta_query', array(
'relation' => 'OR',
'price_clause' => array(
'key' => 'price',
'compare' => 'EXISTS',
'type' => 'NUMERIC',
),
array(
'key' => 'price',
'compare' => 'NOT EXISTS',
),
));
// orderbyでクラス名(price_clause)を直接参照して並び替える
$query->set('orderby', array('price_clause' => $order));
}
}
add_action('pre_get_posts', 'sort_posts_by_price');
これで管理画面の投稿一覧に「価格」カラムが表示され、クリックで昇順・降順に並び替えが可能になります。
meta_key+orderbyだけでは未設定の投稿が一覧から消える
トップレベルの
トップレベルの
meta_keyを指定してorderby => 'meta_value_num'で並び替えると、WordPressは内部的にpostmetaテーブルとINNER JOINします。このため、priceを設定していない投稿は「価格」列でソートした瞬間に一覧から完全に除外されてしまいます。管理者が「投稿が消えた」と誤解しかねない危険な落とし穴です。上記コードのように、名前付きmeta_queryクラス(price_clause)とEXISTS/NOT EXISTSのOR条件を使うことで、priceが未設定の投稿も一覧に残したまま正しくソートできます。カスタム投稿タイプにも対応させる
上記の例は「post」投稿タイプに対するものです。manage_●●_posts_columns や manage_edit-●●_sortable_columns の部分を、カスタム投稿タイプのスラッグに置き換えれば、任意の投稿タイプにも適用できます。
たとえば、カスタム投稿タイプがeventの場合、以下のように登録します(ソート時のクエリ調整用フック自体はpost_typeを問わず共通で使えます)。
functions.php:カスタム投稿タイプへの適用
add_filter('manage_event_posts_columns', 'add_price_column');
add_action('manage_event_posts_custom_column', 'show_price_column', 10, 2);
add_filter('manage_edit-event_sortable_columns', 'make_price_column_sortable');
関連記事
よくある質問(FAQ)
Q管理画面の記事一覧でカスタムフィールドの値でソートするカラムを追加するには?
Amanage_{post_type}_posts_columnsでカラム追加、manage_{post_type}_posts_custom_columnで値を表示、manage_edit-{post_type}_sortable_columnsでソート可能登録、pre_get_postsでmeta_queryとorderbyを設定します。
Q数値・文字列・日付のカスタムフィールドでソートする際の違いは?
A数値はorderby=meta_value_num、文字列はorderby=meta_value、日付(YYYY-MM-DD形式)はorderby=meta_valueで辞書順ソートが有効です。それ以外の形式の日付はmeta_queryのtypeにDATEを指定します。
Qカスタムフィールドが設定されていない記事が一覧から消えてしまうときは?
Aトップレベルのmeta_keyだけを指定するとINNER JOINになり、未設定の投稿が除外されます。本文で紹介した名前付きmeta_queryクラス(EXISTS句とNOT EXISTS句をrelation=>’OR’で並べ、orderbyでクラス名を直接参照する方法)で回避できます。
まとめ
管理画面でカスタムフィールドを使ったソート機能を追加することで、運用効率が大幅に向上します。特にECサイトや案件管理サイトなどで価格・優先度・日付などを管理する場合には非常に便利です。フィールド未設定の投稿が一覧から消えないよう、名前付きmeta_queryクラスを使うことを忘れないようにしましょう。
ACFなどのプラグインと組み合わせることで、より柔軟なカスタマイズも可能になります。実用的な管理画面を構築して、WordPressの操作性を高めましょう。

