ちなみになんでXサーバーの話なのになんでSWELL?というと
XサーバーではWordpressが使え、またテーマとしてSWELLを売っているから。
https://www.xserver.ne.jp/news_detail.php?view_id=10486
せっかく招待してもらったのでこちらについて前回に引き続いてお話させていただく。
---
SWELL を利用した WordPress サイトで、イベント一覧のアーカイブページを「ACF で設定した日付(event-date)を基準に昇順で並べたい」という要件が発生した。
投稿の公開日とは別に、イベント開催日を基準に並べ替える必要があるため、pre_get_posts を用いてメインクエリを書き換える実装を行った。
■ 要件
- イベント一覧は通常の投稿 (
post) を利用 - カテゴリー ID 160 が「イベント一覧」
- ACF のカスタムフィールド
-
event-date(日付)
-
- 表示条件
- 今日以降の未来日のみ
-
event-date昇順で並べ替え
■ 初期実装
まずは一般的な pre_get_posts の記述を用い、カスタムフィールドを基準にソートするコードを作成した。
function modify_event_query($query) {
// 管理画面以外、メインクエリ、event カテゴリにのみ適用
if (!is_admin() && $query->is_main_query() && is_category(160)) {
// 並べ替えに使用するカスタムフィールド
$query->set('meta_key', 'event-date');
$query->set('orderby', 'meta_value_num');
$query->set('order', 'ASC');
// 今日以降のイベントのみを表示
$query->set('meta_query', array(
array(
'key' => 'event-date',
'value' => date('Ymd'),
'compare' => '>=',
'type' => 'NUMERIC',
),
));
}
}
add_action('pre_get_posts', 'modify_event_query');
このコードにより、未来日の投稿だけは取得できたものの、ソート順が正しく昇順にならない問題が発生した。
■ ソートが意図通りに動作しない原因
SWELL は内部でアーカイブクエリの並べ替えに関わる設定を行っている場合があり、
テーマが設定するクエリ操作の方が優先されてしまうことがある。
そのため pre_get_posts のフックが SWELL の処理より先に実行されてしまい、
本来 override したかった orderby が上書きされてしまっていたことが原因である。
■ 解決策:pre_get_posts の優先度を上げる
pre_get_posts の実行タイミングを遅らせることで、テーマ側のクエリ設定を後から上書きできる。
以下のように 優先度を 20 に設定することで正しく並べ替えが機能した。
function modify_event_query($query) {
if (!is_admin() && $query->is_main_query() && is_category(160)) {
$query->set('meta_key', 'event-date');
$query->set('orderby', 'meta_value_num');
$query->set('order', 'ASC');
$query->set('meta_query', array(
array(
'key' => 'event-date',
'value' => date('Ymd'),
'compare' => '>=',
'type' => 'NUMERIC',
),
));
}
}
// 優先度を上げてテーマのクエリ設定を上書き
add_action('pre_get_posts', 'modify_event_query', 20);
add_action('pre_get_posts', ..., 20)
→ SWELL が内部で設定しているクエリより「後に」実行されるため、
指定した orderby が正しく反映されるようになる。
■ まとめ
-
ACF の日付フィールドでソートする場合、
meta_keyとorderby=meta_value_numを設定する -
今日以降の投稿だけを取得したい場合は
meta_queryで範囲指定する -
SWELL を含め、テーマ側がクエリを書き換えている可能性があるため
pre_get_postsの優先度を調整することが重要 -
add_action(..., 20)のように優先度を上げることで意図した並べ替えが可能になる