アーカイブページをページ分割する際に、1ページ目と2ページ目以降で表示する投稿の数を変える、わりとシンプルな方法。
functions.php と archive[-カスタム投稿タイプ名].php のカスタマイズ。
/*functions.php ========================================*/
function change_posts_per_page($query) {
if ( is_admin() || ! $query->is_main_query() ){
return;
}
if ( $query->is_post_type_archive( 'カスタム投稿タイプ名' ) ) {
$first_cnt = 13; // 1ページ目の投稿の表示数
$each_cnt = 12; // 2ページ目以降共通の投稿の表示数
$cnt_delta = $first_cnt - $each_cnt; // 上記の差分
if( !is_paged() ) { // 最初のページの場合
/* 投稿数をセット、完了 */
$query->set( 'posts_per_page', $first_cnt );
return;
} else { // 2ページ目以降の場合
/* 何ページ目かを取得,1はデフォルト */
$paged = get_query_var( 'paged', 1 );
/*
以前のページに表示した投稿数を計算しオフセット
*/
$current_offset = $each_cnt * ( $paged - 1 ) + $cnt_delta;
$query->set( 'offset', $current_offset );
/* 投稿数をセット、完了 */
$query->set( 'posts_per_page', $each_cnt );
return;
}
}
}
add_action( 'pre_get_posts', 'change_posts_per_page' );
まずfunctions.phpに記述するpre_get_posts アクションフック
is_paged()の値で、最初のページかそれ以外のページかを判別し、それぞれに$query->set( 'posts_per_page', 数値 );
の部分で1ページあたりの投稿数を設定している。
しかし posts_per_page について注意しなければならないのは、この値は
現在のページでの表示件数として参照されるだけでなく、その直後に
以前のページの表示件数(offset の値)として使われる点である。
たとえば、最初のページは13件、以降のページを12件としたい時、
2ページ目は、最初のページに既出の13件が取り除かれて(offsetされて)14件目から表示されなければならないが、
WordPressデフォルトのページネーションの仕様では、
2ページ目を12件で表示するためにpost_per_page = 12
とした時点で、offset値も12件となってしまうため、既出の投稿が12件しか省かれず、
2ページ目が13件目から表示されてしまう。(13件目はすでに1ページ目に表示されているので表示が重複することになる)
上記のコードでは、これを防ぐために post_per_page のリセット後に、offset値を適正化を行なっている。
/*archive[-カスタム投稿タイプ名].php ========================================*/
/* ページネーション部分 */
<?php
global $wp_query;
/* functions.phpと同様に */
$first_cnt = 13; // 1ページ目の投稿の表示数
$each_cnt = 12; // 2ページ目以降共通の投稿の表示数
$cnt_delta = $first_cnt - $each_cnt; // 上記の差分
/* 公開済み投稿数の取得 */
$count_posts = wp_count_posts( 'カスタム投稿タイプ名' );
$published_posts = $count_posts->publish;
/* 総ページ数の算出(以下pagenate_linksのパラメータ用に) */
$total = max( 1, ceil( ( $published_posts - $cnt_delta ) / $each_cnt ) );
$big = 999999999; // need an unlikely integer
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $total
) );
?>
ページ送りのUI部分では、totalパラメータに入れる値を補正している。
差分によって全体ページ数にズレが生じるので、それを再算出している。
コメントを残す