WordPressの投稿一覧画面を使いやすくシリーズの第三弾です。
こちらの記事で投稿一覧画面に列を追加しました。
そして、こちらの記事では、絞り込み機能を拡張しました。
今回は第一弾で追加した列で並べ替えをできるようにしていきます。
デフォルトでは、ページタイトルや公開日時で並べ替えができるようになっていますが、追加した列はそのままでは並べ替えは実現できません。
ということで、追加した列の並べ替え機能を実装していきましょう。
手順としては2つのフェーズです。
1
並べ替え機能を実装する
列を指定する
まずは並べ替え機能を実装したい列を指定していきます。
今回は、「コンテンツ」「出版社」「値段」「在庫状況」の列を並べ替えできるようにしていきます。
基本となる大枠のコードは以下のとおりです。
add_filter(
//第一引数 =フィルターフック名
'manage_edit-post_sortable_columns',
//第二引数 = 処理内容
function($columns){
//ここに処理内容を記述
}
//第三引数・第四引数は省略
);
第二引数のコールバック関数を外に出した、以下の記述も同じ意味合いです。
add_filter( 'manage_edit-post_sortable_columns', 'コールバック関数名' );
function コールバック関数名($columns){
//処理内容をここに記述
}
フィルターフックはadd_filter関数で実行します。
第一引数は、使用するフィルターフック名を記述します。
今回はmanage_edit-post_sortable_columnsという、管理画面で並べ替え可能な列を設定するフックを使用します。
固定ページの一覧画面ではmanage_edit-page_sortable_columnsを、カスタム投稿の一覧画面の場合にはmanage_edit-カスタム投稿のスラッグ_sortable_columnsを使用します。
第二引数は、並べ替え可能な列を指定する処理を記述します。
このコールバック関数では、どの列をどのフィールドを使用してソートするのか、という情報を引数として受け取ることができます。
引数$columnsは、
'列の名前' => 'フィールド名'
という配列になっています。
この引数に対して、追加したい列の情報を加えていくのが第二引数の処理内容となります。
ちなみに、manage_edit-post_sortable_columnsでは、コールバック関数で受け取ることができる引数がひとつだけですので、add_filter関数の第三引数と第四引数は省略しています。
具体的なコードは以下になります。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
add_filter('manage_edit-post_sortable_columns','posts_sortable_columns');
function posts_sortable_columns($columns){
$columns['content'] = 'content';
$columns['publisher'] = 'publisher';
$columns['price'] = 'price';
$columns['stock'] = 'stock';
return $columns;
}
3〜6行目で、追加する列の情報を$columnsに追加している処理になります。
列の名前は、第一弾で設定した列の名前を入れてください。
今回、列の名前はフィールド名と同じにしていますので、
$columns['content'] = 'content';
$columns['publisher'] = 'publisher';
$columns['price'] = 'price';
$columns['stock'] = 'stock';
という形で記述しました。
最後に$columnsをreturnして完了です。
簡単ですね。
ちなみに、
$columns['列の名前'] = 'フィールド名';
の記述の場合、一覧の列名部分をクリックすると昇順での並べ替えになり、以降クリックのたびに降順→昇順→降順→・・・となりますが、
$columns['列の名前'] = array( 'フィールド名',true);
とすると、一度めのクリックで降順、以降、昇順→降順→昇順→・・・とすることができます。
これで並べ替え機能はできました、と言いたいところですが、カスタムフィールドの列の場合には、並べ替えがうまく機能しない場合があります。
今回のケースでは、「出版社」「値段」「在庫状況」がカスタムフィールドによる列。
ということで、カスタムフィールド列の場合には一手間加えます。
2
(カスタムフィールドの場合)
正しく並べ替えできるように一手間加える
そもそも、投稿一覧画面での並べ替えはどのように行われているのか。
そのヒントがアドレスバーにあります。
例えば、手順1で設定した「コンテンツ」をクリックして、アドレスバーを確認してください。
URLの末尾に
?orderby=content&order=asc
というパラメータが追加されていることがわかると思います。
WordPressの一覧画面はメインクエリ(WP_Query)によってDBからの情報が絞り込まれ、表示されています。投稿一覧画面であればpost_typeがpost、固定ページの一覧画面であればpage、といった具合に絞り込まれているわけです。
並べ替え機能は、このメインクエリにURLパラメーターの情報が追加されることで実装されています。
手順1での設定は、URLパラメーターに、
orderby=content
order=asc
を加えることで並べ替えを実現するというものだったのです。
ただし、カスタムフィールドの場合のクエリは、
orderby=meta_value(もしくはmeta_value_num)
meta_key=カスタムフィールド名
という具合に指定しなければならないルールですので、手順1の設定だけではうまくソートできない場合があるということなのです。
ということで、URLパラメータをカスタムフィールドの場合のクエリに書き換えてあげるのが、この手順になります。
基本の大枠コードは以下になります。
add_filter(
//第一引数 = フィルターフック名
'request',
//第二引数 = 処理内容
function($query_vars){
//並べ替え条件の設定
}
//第三引数・第四引数は省略
);
使用するフィルターフックはrequestで、第二引数のコールバック関数で記述した処理内容がメインクエリに渡される仕組みです。
第二引数のコールバック関数を見ていきましょう。
function($query_vars){
if(is_admin()){
//それぞれの項目の設定
}
}
1行目ですが、コールバック関数の引数ではメインクエリで使用するパラメータの配列を取得することができます。ここに、ソートするフィールドごとにパラメータ情報を追加していくのが主な処理内容になります。
注意点としてrequestはフロントを含めて全てのページに影響するフィルターフックですので、管理画面のみで機能するように条件分岐させることが重要です(2行目)。
その上で、カスタムフィールドを利用した列ごとに設定していきます。
出版社の場合には、
if(isset( $query_vars['orderby'] ) && 'publisher' === $query_vars['orderby'] ) {
$query_vars['meta_key'] = 'publisher';
$query_vars['orderby'] = 'meta_value';
}
となります。
メインクエリで使用するパラメータに’orderby’の設定があり、かつ、その値が’publisher’の場合(1行目)、2行目以降の処理を行います。
2〜3行目は、$query_varsの’meta_key’に’publisher’を、’orderby’に’meta_value’を設定する処理となります。
全体のコードは以下になります。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
add_filter('request', 'query_filter');
function query_filter($query_vars){
//管理画面のみに適用
if(is_admin()){
//出版社の設定
if(isset( $query_vars['orderby'] ) && 'publisher' === $query_vars['orderby'] ) {
$query_vars['meta_key'] = 'publisher';
$query_vars['orderby'] = 'meta_value';
}
//値段の設定
if(isset( $query_vars['orderby'] ) && 'price' === $query_vars['orderby'] ) {
$query_vars['meta_key'] = 'price';
$query_vars['orderby'] = 'meta_value_num';
}
//在庫状況の設定
if(isset( $query_vars['orderby'] ) && 'stock' === $query_vars['orderby'] ) {
$query_vars['meta_key'] = 'stock';
$query_vars['orderby'] = 'meta_value';
}
}
return $query_vars;
}
ちょっと重複がありますので、少し整理します。
add_filter('request', 'query_filter');
function query_filter($query_vars){
//管理画面 かつ メインクエリのパラメータにorderbyが設定されている際に適用
if(is_admin() && isset($query_vars['orderby'])){
switch($query_vars['orderby']){
//出版社の設定
case 'publisher':
$query_vars['meta_key'] = 'publisher';
$query_vars['orderby'] = 'meta_value';
break;
//値段の設定
case 'price':
$query_vars['meta_key'] = 'price';
$query_vars['orderby'] = 'meta_value_num';
break;
//在庫状況の設定
case 'stock':
$query_vars['meta_key'] = 'stock';
$query_vars['orderby'] = 'meta_value';
break;
}
}
return $query_vars;
}
少し、見通しが良くなったのではないでしょうか。
これでカスタムフィールドの列もうまくソートできるようになりました。
(URLパラメータは変化ないのですが、内部では上記の設定が反映されています)
3
まとめ
一覧画面の並べ替えは地味な機能かもしれませんが、投稿数が多くなればなるほど意外と便利な機能だと思います。第二弾で紹介した絞り込み機能よりもシンプルな考え方で実装できますので、やらない手はないと思います。
第一弾、第二弾もぜひ合わせてご確認ください。
最後に今回のすべてのコードを以下にまとめます。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
/*----------------
* 並べ替え機能を実装する列を指定する
*----------------*/
add_filter('manage_edit-post_sortable_columns','posts_sortable_columns');
function posts_sortable_columns($columns){
$columns['content'] = 'content';
$columns['publisher'] = 'publisher';
$columns['price'] = 'price';
$columns['stock'] = 'stock';
return $columns;
}
/*----------------
* (カスタムフィールドの場合)正しく並べ替えできるように一手間加える
*----------------*/
add_filter('request', 'query_filter');
function query_filter($query_vars){
//管理画面 かつ メインクエリのパラメータにorderbyが設定されている際に適用
if(is_admin() && isset($query_vars['orderby'])){
switch($query_vars['orderby']){
//出版社の設定
case 'publisher':
$query_vars['meta_key'] = 'publisher';
$query_vars['orderby'] = 'meta_value';
break;
//値段の設定
case 'price':
$query_vars['meta_key'] = 'price';
$query_vars['orderby'] = 'meta_value_num';
break;
//在庫状況の設定
case 'stock':
$query_vars['meta_key'] = 'stock';
$query_vars['orderby'] = 'meta_value';
break;
}
}
return $query_vars;
}