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/ […]