一覧ページの表示順をクリック一つで変更
Image by Lothar Dieterich from Pixabay
2023.03.17(更新日:2023.03.17)
アーカイブページやタクソノミーページなどでのお話。
通常「ASC or DESC」でループすれば済むところを「○○順」なんてボタンパーツを希望されたりしませんか?
それも基準値をカスタムフィールド値とかにされると「面倒くせー!」となる。
そんなに需要があるのか?と疑いつつも希望されると仕方がない。
すぐ忘れるのそのでまとめ。
この記事は1年以上経過しています。内容的に古い場合があります。
通常ループ
WordPressはそれぞれのページに適した記事データを取得してくれるので「降順」であれば何もすることはない。
けれど今回、その順番をいじくるのでとりあず「WP_Query」の出番かなと。
単純に「降順 / 昇順」オンリーのものは以下になる。
/* テンプレート内 */
<?php
$args = array(
'post_type' => $post_type, //投稿タイプ
'orderby' => 'date', //何を表示順の基準とするか
'order' => 'DESC', //昇順か降順
'post_status' => 'publish', //公開状態
'posts_per_page' => -1, //何件表示か(-1で全件)
'tax_query' => array( //カテゴリーなどのタクソノミーのタームを指定したい場合
array(
'taxonomy' => $taxonomy, //タクソノミー
'field' => 'slug', //タームの絞り込む種別
'terms' => $terms //その値
)
)
);
$loop = new WP_Query( $args );
if( $loop->have_posts() ) :
while( $loop->have_posts() ) : $loop->the_post();
//何か処理する
endwhile;
endif;
wp_reset_postdata(); //必須。WP_Queryを使ったら書く!
?>
なぜか良く「どっちだっけ?」となるので念のため。「order」部分に入る値は
- ASC・・・昇順(小さいもの順/例:123)
- DESC・・・降順(大きいもの順/例:321)
になる。ちなみにデフォルトでは「DESC」。WP_Queryは各値を変えたら、どーにでもなると言う素晴らしい代物。
配列の中身を変える
上記のコードで「昇順 / 降順」に変える方法はご理解いただけると思う。
ではカスタムフィールドではどうするかだが
/* 引数 */
$args = array(
'post_type' => $post_type, //投稿タイプ
'meta_key' => $meta_key, //カスタムフィールドのキー
'orderby' => 'meta_value', //何を表示順の基準とするか
'order' => 'DESC', //昇順か降順
⋮
);
で出来るはず。もちろん「meta_value」が比較出来る値(数値や日付など)が前提。
分岐をどうするか
ここまでで引数の値を変えて「WP_Query」にぶち込めば問題ないことがわかる。
どう分岐させるかはURLパラメータで処理する・・・なんだが何でもかんでも使える訳ではない。
予め登録されているもの以外は登録しないと使えないので
/* functions.phpとかに付加 */
function custom_query_vars( $vars ) {
$vars[] = 'meta_key';
⋮ //上の行の要領で付加
return $vars;
}
add_filter( 'query_vars', 'custom_query_vars' );
の様に登録設定する。デフォルトで使えるパラメータは以下参照。
表示順切り替え用のリンクを設置
表示切り替え用のリンクにはパラメータを付加したものを使う。
以下の例はカスタム投稿のアーカイブページの例。パラメータは仕様に合わせて変更。
/* テンプレート内 */
<?php
$archive_link = get_post_type_archive_link( $post_type );
$desc = esc_url( add_query_arg( 'order', 'desc', $archive_link ) );
$asc = esc_url( add_query_arg( 'order', 'asc', $archive_link ) );
//orderbyやら複数入れ替えるなら以下の感じで
$field = esc_url( add_query_arg( array('order'=>'desc', 'meta_key'=>$meta_key ), $archive_link ) );
?>
<ul>
<li><a href="<?php echo $desc; ?>">降順</a></li>
<li><a href="<?php echo $asc; ?>">昇順</a></li>
<li><a href="<?php echo $field; ?>">カスタムフィールド順</a></li>
</ul>
パラメータで分岐
ここまで出来たら、パラメータを受け取って分岐するだけ。
/* WP_Query処理の前に */
$order = get_query_var( 'order' );
$meta_key = get_query_var( 'meta_key' );
// ⋮ とパラメータを受け取って
$args = array( //基本的に変わらない部分のみ入れといて
'post_type' => $post_type, //投稿タイプ
⋮
);
if( !empty( $order ) ) $args[ 'order' ] = $order;
if( !empty( $meta_key ) ) $args[ 'meta_key' ] = $meta_key;
// ⋮ と$argsに追加
$loop = new WP_Query( $args );
ゴチャゴチャになる場合は、それぞれ配列の引数をちゃんと書いて分けた方がいいかも。間違いないし可視性もいいしね。