イベントの開催日など、投稿日付とは違うカスタムフィールドに入力された値の順で一覧ページを並び替えたいとします。
start_date というカスタムフィールドの値を使って昇順(ASC)に並び替える方法をとります。
しかし、start_date が空の投稿があるときには、単なる昇順では問題が出るためその解決方法までをまとめた記事です。
準備
カスタムフィールドの設定(Advanced Custome Fields デイトピッカー の場合)
表示フォーマットは好きな設定に、返り値のフォーマットは並び替えで利用したいので Ymd にしておきます。
表示テンプレートの設定(ループの中部分のみ)
ループの中のテンプレートはとりあえずこんな感じにします。
<div>
<h2>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h2>
<dl>
<dt>開催日</dt>
<dd>
<?php
if(get_field('start_date')){
//開始日があれば、開始日の日付フォーマットを調整して表示
$start_date = date_create(get_field('start_date'));
echo date_format($start_date, 'Y年n月j日');
}else{
//開始日に入力がないなら未定に
echo '未定';
}
?>
</dd>
</dl>
</div>
カスタムフィールドの値を使って並び替える
投稿タイプ event の一覧を、カスタムフィールド start_date の昇順(日付が古い順)に並べます。
if ( have_posts() ) : while ( have_posts() ) : the_post();
で表示している一覧なら、functions.phpにpre_get_postsを使って以下のように。
add_action( 'pre_get_posts', function($query) {
if ( is_admin() || ! $query->is_main_query() ){
return;
}
if($query->is_post_type_archive('event')){
$query->set('meta_key', 'start_date');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
});
また、そうではなくnew WP_Query()
を使って表示させている一覧なら、WP_Queryの引数をこんな感じに
$args= array(
'post_type'=>'event',
'meta_key' =>'start_date',
'orderby' =>'meta_value',
'order' => 'ASC'
);
$event_query = new WP_Query($args);
昇順(ASC)にすると、フィールドが空のものが先頭に来てしまう。
並び替えはうまくできましたが、この場合、未定のもの(start_dateが空の投稿)は一番最後に来てほしいです…。
カスタムフィールドを使ったorderbyを調整する
orderの設定にはASCかDESCしかなく、空は0(一番小さい値)として扱われるため、そのままでは目的が達成できません。
が、posts_orderby
というフィルターを使って、orderbyの動きを変えることができます。
まずは以下のように、functions.phpに準備します。
add_filter( 'posts_orderby', function($orderby, $query ) {
if ( $query->get( 'custom_orderby' ) ) {
$orderby = 'wp_postmeta.meta_value+0 > 0 DESC, ' . $orderby;
}
return $orderby;
}, 10, 2);
そしてif ( have_posts() ) : while ( have_posts() ) : the_post();
で表示している一覧なら、pre_get_postsを以下のように。
add_action( 'pre_get_posts', function($query) {
if ( is_admin() || ! $query->is_main_query() ){
return;
}
if($query->is_post_type_archive('event')){
$query->set('meta_key', 'start_date');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
$query->set('custom_orderby', 'true'); // 追加
}
});
そうではなくnew WP_Query()
を使って表示させている一覧なら、WP_Queryの引数をこんな感じに。
<?php
$args= array(
'post_type'=>'event',
'meta_key' =>'start_date',
'orderby' =>'meta_value',
'order' => 'ASC',
'custom_orderby' => true // 追加
);
$event_query = new WP_Query($args);
フィールドの値が空の投稿を一番下、それ以外は昇順で並べることができた。
これで無事に開催日フィールドが空の投稿を一番下に移動することができました。
コメント