WordPressで1ページ目と2ページ目以降で表示件数を変更する方法を調べてみました。WordPressでは、基本的に1ページの表示件数は固定されています。このため、1ページ毎の表示件数を変える処理が必要になります。なので力技で変更してみました。
pre_get_postsフック
WordPressの処理をカスタマイズするときに重宝するのが、フックです。フックは、WordPressの処理に割り込みを入れることができます。このおかげで、WP本体のコードを改変しないでWPの挙動をカスタマイズすることができます。
今回は、1ページの表示数を変更したい、です。1ページの表示数は、メインループに関係しますね。なので、メインループ処理をカスタマイズします。メインループの処理を変更するにはpre_get_postsフックが役立ちます。このフックはクエリを実行する前に呼び出されます。(query_posts等でデータを取得しなおすよりも高速です)
まずは単純な例をみてみましょう。1ページの表示件数を5件にするコードです。
add_action( 'pre_get_posts', 'mypaging' );
function mypaging($query) {
if ( is_admin() || ! $query->is_main_query() ) { // 管理画面を表示している場合を除外。またメインループでない場合を除外
return;
}
$query->set('posts_per_page',5);
}
is_admin() || ! $query->is_main_query() の部分は、管理画面を表示している場合、メインループでない場合を除外しています。今回の中心となるコードは$query->set('posts_per_page',5);です。「posts_per_pageの値を5にする」という命令になります。こうすることで、1ページの表示件数を変更できました。
2ページ目以降で値を変更する
全ページで表示件数を変更するのであれば、上のコードでOKです。では「2ページ目以降」と条件をつけたい場合はどうでしょうか?この場合、get_query_var( 'paged' )で何ページ目か、を取得することができます。この値で条件判定すればよいですね。
$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1; // twentyfourteen_paging_nav より
if ($paged >= 2){ // 2ページ目以降の場合
$query->set('posts_per_page',5); // 1ページに5件ずつ表示
}
1行目は twentyfourteen テーマの twentyfourteen_paging_nav をコピーしています。2行目からのif文では、「2ページ目以降なら、5件ずつ表示」にしています。(1ページ目は、管理画面で設定した表示件数が適用されます)
表示の開始を調整
さて、単純に、「2ページ目以降なら、5件ずつ表示」にした場合、2ページでは6件目から10件目が表示されます。もし1ページ目に3件だったら、4件目5件目が表示されないですね。逆に1ページ目に10件だったら、6-10件目は重複して表示されてしまいます。
なので、表示の開始を調整する必要があります。$query->set('offset',5);のように、offsetを設定します。
define('POSTS_PER_PAGE_FOR_1ST',3); // 1ページ目の件数
define('POSTS_PER_PAGE_FOR_2ND',5); // 2ページ目の件数
add_action( 'pre_get_posts', 'mypaging' );
function mypaging($query) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
if ($paged >= 2){
$query->set('offset', POSTS_PER_PAGE_FOR_1ST + POSTS_PER_PAGE_FOR_2ND*($paged-2) );
$query->set('posts_per_page',POSTS_PER_PAGE_FOR_2ND);
}
}
offset の値は、何ページ目か、によって異なります。計算式は POSTS_PER_PAGE_FOR_1ST + POSTS_PER_PAGE_FOR_2ND*($paged-2) です。2ページ目の場合は「1ページ目の件数」、3ページ目の場合は「1ページ目の件数 + (2ページ目以降の件数 * 1)」、4ページ目の場合は「1ページ目の件数 + (2ページ目以降の件数 * 2)」、となります。
POSTS_PER_PAGE_FOR_1ST、POSTS_PER_PAGE_FOR_2NDは適宜設定してください。
これで、ページにアクセスされたときの表示調節ができました。続いてページへのリンク(ページナビ)を変更します。
ページナビのページ数を変更する
1ページ目と2ページ目以降で表示件数を変更した場合、ページナビのページ数も、それにあわせて変更する必要があります。twentyfourteen ベースの場合、inc/template-tags.phpにあるtwentyfourteen_paging_nav 関数を変更します。ページ数は、41行目paginate_linksの’total’で指定されています。元は'total' => $GLOBALS['wp_query']->max_num_pages,となっています。ここを書き換えます。
'total' => 1 + ceil(($GLOBALS['wp_query']->found_posts - POSTS_PER_PAGE_FOR_1ST)/POSTS_PER_PAGE_FOR_2ND),
に書き換えます。「全投稿数から1ページ目の表示件数を引いたもの」を「2ページ目以降の表示件数」で割ります。そうすると2ページ目以降のページ数が分かります。この値が3なら、2ページ、3ページ、4ページ、ということですね。なので、それに1を足せば全ページ数になります。
全体のコード
全体のこーどは下記のとおりです。twentyfourteenの子テーマを使っている場合、functions.phpにコピーするだけで実現できます。WordPressではこのような複雑なページング処理も行うことができます。
define('POSTS_PER_PAGE_FOR_1ST',5);
define('POSTS_PER_PAGE_FOR_2ND',10);
add_action( 'pre_get_posts', 'mypaging' );
function mypaging($query) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
if ($paged >= 2){
$query->set('offset',POSTS_PER_PAGE_FOR_1ST+($paged-2)*POSTS_PER_PAGE_FOR_2ND);
$query->set('posts_per_page',POSTS_PER_PAGE_FOR_2ND);
}
}
// twentyfourteen のコードを元にしています
if ( ! function_exists( 'twentyfourteen_paging_nav' ) ) :
/**
* Display navigation to next/previous set of posts when applicable.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_paging_nav() {
// Don't print empty markup if there's only one page.
if ( $GLOBALS['wp_query']->max_num_pages < 2 ) {
return;
}
$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
$pagenum_link = html_entity_decode( get_pagenum_link() );
$query_args = array();
$url_parts = explode( '?', $pagenum_link );
if ( isset( $url_parts[1] ) ) {
wp_parse_str( $url_parts[1], $query_args );
}
$pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
$pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
$format = $GLOBALS['wp_rewrite']->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
$format .= $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit( 'page/%#%', 'paged' ) : '?paged=%#%';
// この行を追加
$total = 1 + ceil(($GLOBALS['wp_query']->found_posts - POSTS_PER_PAGE_FOR_1ST)/POSTS_PER_PAGE_FOR_2ND);
// Set up paginated links.
$links = paginate_links( array(
'base' => $pagenum_link,
'format' => $format,
'total' => $total,
'current' => $paged,
'mid_size' => 1,
'add_args' => array_map( 'urlencode', $query_args ),
'prev_text' => __( '← Previous', 'twentyfourteen' ),
'next_text' => __( 'Next →', 'twentyfourteen' ),
) );
if ( $links ) :
?>
<nav class="navigation paging-navigation" role="navigation">
<h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'twentyfourteen' ); ?></h1>
<div class="pagination loop-pagination">
<?php echo $links; ?>
</div><!-- .pagination -->
</nav><!-- .navigation -->
<?php
endif;
}
endif;
[…] 、コピペはダメです。 1ページ目と2ページ目以降の表示件数を変える場合、ifで分岐させる必要があります。 コチラのサイト様が参考になります→https://ounziw.com/2014/07/11/wordpress-pre_get_posts/ […]