pre_get_postsでメインクエリを変更した際の次/前リンクの取得する方法

作成日:

WordPressでは、pre_get_postsを使用することで、メインクエリで取得される記事の順番をカスタマイズすることができます。
例えば「イベント投稿」では、並び順をカスタムフィールドで設定した「開催日」に変更するなど。

しかし、pre_get_postsをカスタマイズするだけでは該当する記事の「次の投稿」「前の投稿」を取得するnext_post_linkprevious_post_linkでは、標準の日付順となり、メインクエリの通りにはなりません。

そこで色々と調べてみたのですが、SQLを記述して取得するような手段しか見つかりませんでした。

Wordpress 記事を属性 順序( menu_order ) の順番に並べたい https://chaika.hatenablog.com/entry/2014/10/16/024556

Wordpressの固定ページには属性の欄に順序があり表示する順番を決めることができます。 この順序ですが投稿やカスタム投稿でもこの属性欄を表示させることがで、順序に入力した順番で表示させることもできます。

これでも行けると思うのですが、SQLで、となると記述が面倒な気も致します。

そこで他に何か代替手段は無いかと模索していましたが、結局は

同条件のWP_Queryから記事IDの配列を取得

して、記事IDキーの前後キー値を次/前の記事リンクを出力すれば簡単なのでは無かろうかと。

📝 今回の例
  • カスタム投稿 | my_event
  • 開催日(カスタムフィールド) | from_date
PHP
// single.phpで表示中の記事ID取得.
$current_ID = get_the_ID();
// pre_get_postsと同じクエリ条件を指定.
$args = array(
	'post_type'      => 'my_event',
	'post_status'    => 'publish',
	'posts_per_page' => -1,
	'meta_key'       => 'from_date',
	'orderby'        => 'meta_value_num',
	'order'          => 'DESC',
	'fields'         => 'ids', // これでID配列を取得出来る.
);
$nav_query  = new WP_Query( $args );
// これで$post_arrayにクエリ条件下の記事IDが配列として格納される.
$post_array = $nav_query->posts;
wp_reset_postdata();
// 記事IDのキーを取得.
$current_index = array_search( $current_ID, $post_array );
// 次/前の記事IDを取得.
if ( $current_index ) {
	$next_post_ID = $post_array[ $current_index + 1 ];
	$prev_post_ID = $post_array[ $current_index - 1 ];
	// 次の記事.
	echo '<a href="' . get_permalink( $next_post_ID ) . '">' . get_the_title( $next_post_ID ) . '</a>';
	// 前の記事.
	echo '<a href="' . get_permalink( $prev_post_ID ) . '">' . get_the_title( $prev_post_ID ) . '</a>';
}

これで何とかはなるかな。
重いかな。

物草 灸太郎

WordPressでホームページを制作しつつ、休日は畑を耕したりDIYを楽しんでいます。

コメント

Berghilo さん
if ( $current_index ) { を外したら、最初と最後もちゃんと表示されました。 また、前の記事と次の記事には if ( $prev_post_ID ) と if ( $next_post_ID ) をつけました。 ありがとうございます。
2022年6月14日 1:17 PM 返信
Berghilo さん
まさに求めているものでした。 大感謝です。 でも、一点だけ。 次・前ページの最初と最後のページなんですが、 最初のページ:何もリンクされない。 最後のページ:自分自身をリンクしてしまう。 という結果でした。 もし可能ならご確認ください。 よろしくお願いします。
2022年6月13日 10:17 AM 返信

コメントをどうぞ

  • メールアドレスが公開されることはありません。
  • コメント欄にURLは入力できません。
  • このサイトはreCAPTCHAによって保護されており、Googleのプライバシーポリシー利用規約が適用されます。