front-pageのサブクエリでページネーション

front-pageのサブクエリでページネーション

front-page.phpでサブクエリを使用指定場合のページネーションの作成方法について紹介します。

メインクエリを使用している場合はおそらく問題ないと思いますが、サブクエリの場合は2ページ目がつながりません。

ページネーションがうまくつながらなくて悩んでいる方は参考にしてみてください。

状態

解決前の状態を示します。

まずfront-page.phpは以下のように取得していました。

<?php get_header(); ?>
			<?php get_sidebar(); ?>
			<main>
				<?php 
					$query_arg = [
						'post_type'      => 'movie',
            'paged'          => get_query_var( 'paged' )
						'post_per_page'  => 60,
					];
					$query = new WP_Query( $query_arg );
					if( $query->have_posts() ) :
						while( $query->have_posts() ) :
							$query->the_post();
				 ?>
				      <?php get_template_part( 'parts/card' ); ?>
				 <?php 
					endwhile;
				 	endif;
          my_page_navi( $query );
          wp_reset_postdata();
				 ?>
			</main>
<?php get_footer(); ?>

不要なタグは取り除いています。

サブクエリを作成して、その内容を表示しています。通常トップページのメインクエリはWordPressの表示設定で行ったものの取得クエリになっています。投稿一覧であれば投稿一覧を取得するためのクエリです。

クエリでページ当たりの表示数と現在ページを指定しています。

ページネーションの関数は以下の感じです。

function my_page_navi( $query ) {
  $bignum = 999999999;
  if ( $query->max_num_pages <= 1 )
    return;
  echo '<nav class="pagination">';
  echo paginate_links( array(
    'base'         => str_replace( $bignum, '%#%', esc_url( get_pagenum_link($bignum) ) ),
    'format'       => '',
    'current'      => max( 1, get_query_var('paged') ),
    'total'        => $query->max_num_pages,
    'prev_text'    => '←',
    'next_text'    => '→',
    'type'         => 'list',
    'end_size'     => 3,
    'mid_size'     => 3
  ) );
  echo '</nav>';
} 

Bonesについていたデフォルトのものです。

それをメインクエリで動作するものから引数のクエリで動くようにしたものです。

トップページでページ遷移する前の状態ではしっかりと指定した表示数が表示されます。

しかし、ページ遷移すると404となってしまう状態です。

解決

いろいろとログ出力してみた結果、、、

ページ遷移後に「paged」はとれているけれど、front-page.phpの処理がされていなさそうということ。

違うページとして認識されていそうな感じです。なので、404が出てきます。

そしてもう一つ決定的な点がページ遷移されるとクエリが消えてしまっていたということです。

そのため以下のように対策しました。

add_action( 'pre_get_posts', function( $query ) {
	if( is_admin() || ! $query->is_main_query() ) {
		return;
	}

	if( $query->is_front_page() ) {
		$paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged') ) : 1;
		$query->set( 'paged', $paged );
		if( $paged != 1 ) {
			$query->set( 'post_type', 'movie' );
      $query->set( 'posts_per_page', 45 );
		}
		return;
	}
} );

front-page.phpで作成したサブクエリの条件と同様のものを「pre_get_posts」で指定しました。

これで1ページ目以外でも同様のクエリが指定され正常な表示することが可能となりました。

最後に

あまり使用することはないかもしれませんが、ページネーション周りはつまり易いポイントだと思います。

今回の例は「front-page.php」でのサブクエリに対してのページネーション例です。