列の追加方法は 管理画面の投稿一覧に列を追加する にて解説しています。
- 投稿一覧に列を追加する
- 投稿一覧に絞り込みを追加する
- 投稿一覧の追加列にソート機能をつける
タイトルはデフォルトでソート可能ですが、著者列は独自に追加した列なのでソートができません。ここでは ▲ マークなど表示して、並び替えて表示ができるようにします。
ジャンルはタクソノミーのため、簡単に並び替え表示する方法が WordPress コアでは提供されていません。

投稿タイプの仕様は下記の通り
- 書籍
book
投稿タイプ written_by
カスタムフィールド、表示名「著者」genre
タクソノミー、表示ラベル「ジャンル」
使用するフック
既存ソートの動作をみる
タイトルの横には、ソートのための▲マークが既に表示されるのでソートして表示させてみます。

タイトル順に昇順でソート表示されました。この時、URLにパラメターが追加されています。

追加されるパラメターは
orderby=title&order=asc
タイトル昇順でソート表示されているときorderby=title&order=desc
タイトル降順でソート表示されているとき
ソート可能な列に登録
スクリーン ID について
manage_{$this->screen->id}_sortable_columns フックを使って「著者列」を加えます。そのためには、スクリーンIDを特定する必要があります。
スクリーン ID は管理画面ごとに WordPress コアにより付与されます。get_current_screen 関数などで取得できます。
- 通常投稿の一覧画面:
edit-post
- 書籍投稿の一覧画面:
edit-book
よって、書籍投稿タイプの一覧に適用するためのフック名は manage_edit-book_sortable_columns
ソート可能な列に追加
無名関数を使います。フックの引数 $sortable_columns
配列に、列名をキーとしてソート名を追加。
一旦、sort_written_by
というソート名として、著者列でのソートを追加してみます。
add_filter(
'manage_edit-book_sortable_columns',
function ( $columns ){
$columns['written_by'] = 'sort_written_by';
return $columns;
},
10,
1
);

▲ マーククリックで、画面が切り替わります。一見、並び変わったように見えますが、単にデフォルトから逆順に並んだだけです。著者順には並んでいません。

ここでは URL に &orderby=sort_written_by&order=asc
というパラメターが追加されました。
$sortable_columns
配列に追加した sort_written_by
が orderby
パラメターの値としてセットされます。すなわち、著者列 written_by
の ▲ マークでソートすると sort_written_by
というソートモードに画面が切り替わります。
分かりやすくするために冗長にしていた値を修正して、最終的にはこのようなコードとします。
add_filter(
'manage_edit-book_sortable_columns',
function ( $columns ){
$columns['written_by'] = 'written_by';
return $columns;
},
10,
1
);
次に、実際に著者順で並ぶようにクエリーを調整します。
クエリーを調整
まず、管理画面の書籍投稿の一覧画面かどうかの判定を実装します。
add_action(
'pre_get_posts',
function ( $query ) {
if ( ! is_admin()
|| ! $query->is_main_query()
|| ! isset( $query->query['post_type'] )
|| ! isset( $query->query['orderby'] ) ) {
return;
}
if ( 'book' !== $query->query['post_type'] ) {
return;
}
// このセクションは書籍投稿の一覧画面で、ソートモードの時にのみ実行される.
return;
},
);
こういう時は、自分は早期リターン( early return ) を使って実装しています。
ここまで判定を増やさなくても、 is_admin()
$query->is_main_query()
と投稿タイプ判定の3つでいいような気もします。
次にカスタムフィールドでソートするための $query
の調整を実装します。
検索すると、set( 'meta_key', value )
と set( 'orderby', value )
でできる情報が出てきます。
$query
は WP_Query
オブジェクトなので、公式リファレンスも見ておきます。
WP_Query – Class | Developer.WordPress.org
下記のコード例がみつかりました。
Display posts with ‘Product’ type ordered by ‘Price’ custom field:
$args = array( 'post_type' => 'product', 'orderby' => 'meta_value_num', 'meta_key' => 'price', ); $query = new WP_Query( $args );
orderby
で比較方法を指定、meta_key
でソートの基準にするカスタムフィールドを指定すればよさそうです。
よって、クエリーの調整は
$query->set( 'meta_key', 'written_by' );
$query->set( 'orderby', 'meta_value' );
URLパラメターが&orderby=written_by
の時に、written_by
フィールド基準にソートして欲しいので、さらに条件判定を追加
if( 'written_by' === $query->query['orderby'] )
pre_get_query
フックで実行する最終的なコードはこうなります。
add_action(
'pre_get_posts',
function ( $query ) {
if ( ! is_admin()
|| ! $query->is_main_query()
|| ! isset( $query->query['post_type'] )
|| ! isset( $query->query['orderby'] ) ) {
return;
}
if ( 'book' !== $query->query['post_type'] ) {
return;
}
if( 'written_by' === $query->query['orderby'] ){
$query->set( 'meta_key', 'written_by' );
$query->set( 'orderby', 'meta_value' );
}
return;
},
);
動作確認


著者順でソート表示できました。漢字の著者名の場合、シフトJIS → UTF でコードが若い順になりますので、綺麗な50音にはなりませんが。
最終的なコード
add_filter(
'manage_book_posts_columns',
function ( $columns ){
$written_by_column = array(
"written_by" => "著者"
);
$new_columns = array_slice( $columns, 0, 1 )
+ $written_by_column
+ array_slice( $columns, 1, count( $columns ) - 1 );
return $new_columns;
},
10,
1
);
add_action(
'manage_book_posts_custom_column',
function ( $column_name, $id ) {
if ( 'written_by' === $column_name ) {
echo get_post_meta( $id, 'written_by', true );
}
},
10,
2
);
add_filter(
'manage_edit-book_sortable_columns',
function ( $columns ){
$columns['written_by']='written_by';
return $columns;
},
10,
1
);
add_action(
'pre_get_posts',
function ( $query ) {
if ( ! is_admin()
|| ! $query->is_main_query()
|| ! isset( $query->query['post_type'] )
|| ! isset( $query->query['orderby'] ) ) {
return;
}
if ( 'book' !== $query->query['post_type'] ) {
return;
}
if( 'written_by' === $query->query['orderby'] ){
$query->set( 'meta_key', 'written_by' );
$query->set( 'orderby', 'meta_value' );
}
return;
},
);
add_action(
'admin_print_styles',
function () {
echo '<style>
.column-written_by {
width: 10rem;
}
</style>' . PHP_EOL;
}
);