WordPressでページ種類毎に表示件数(posts_per_page)を変更する方法

WordPressでカテゴリやアーカイブの投稿の表示件数は設定画面から変更できるが、「このカテゴリは特別にXX件表示にしたい」のよう、個別に表示件数を変えたい場合がある。
調べると、カテゴリページで希望の件数をposts_per_pageパラメーターに指定してquery_postsを再度呼び出す方法が紹介されているが、これだともう一度検索処理が入って非効率な気がする。

WordPressのソースを追いかけてみると、wp-includes/query.php WP\_Query::get_posts に**pre_get_posts**というアクションがあった。 WordPress Codex を参照するとちゃんと投稿数を変更するサンプルも記載されていた。

Change the number of posts per page by post type pre_get_posts | Hook | WordPress Developer Resources


function hwl_home_pagesize( $query ) {
    if ( is_admin() || ! $query->is_main_query() )
        return;

    if ( is_home() ) {
        // Display only 1 post for the original blog archive
        $query->set( 'posts_per_page', 1 );
        return;
    }

    if ( is_post_type_archive( 'movie' ) ) {
        // Display 50 posts for a custom post type called 'movie'
        $query->set( 'posts_per_page', 50 );
        return;
    }
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );

このコードを参考にカテゴリ名が’iphone’の場合に表示件数を変更してみると、functions.phpにアクションを追加すると、期待通り件数を変更することができた。

/**
 * @param $query WP_Query
 */
function my_custom_post_per_page( $query )
{
    if( is_admin() || !$query->is_main_query() )
        return;

    if( $query->get( 'category_name' ) == 'iphone' ){
        $query->set( 'posts_per_page', 30 );
    }
}

add_action( 'pre_get_posts', 'my_custom_post_per_page' );