How can I display 7 posts on the home page, but 9 posts on the subsequent pages?

Ok this was really tricky. I have so far managed to work around it by lying to the WordPress global $wp_query. Here is how.

In your theme’s functions.php you can add these functions to show 7 posts on first page, and 9 posts on any other page.

Okay, that code works so far but you’ll notice that the pagination is incorrect on first page. Why? This is because WordPress uses the posts per page on first page (which is 7) and get the number of pages by doing division like ( 1000 / 7 ) = total posts. But what we need is to make the pagination take into account that on next pages we’ll show 9 posts per page, not 7. With filters, you cannot do this but if you add this hack to your template just before the_posts_pagination() function it’ll work as you expect.

The trick is to change the max_num_pages inside $wp_query global variable to our custom value and ignore WP calculation during the pagination links display only for first page.

global $wp_query;

// Needed for first page only
if ( ! $wp_query->is_paged ) {
    $all_posts_except_fp = ( $wp_query->found_posts - 7 ); // Get us the found posts except those on first page
    $wp_query->max_num_pages = ceil( $all_posts_except_fp / 9 ) + 1; // + 1 the first page we have containing 7 posts
}

And this is the code to put in functions.php to filter the query.

add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {

    if ( ! $query->is_home() ) {
        return;
    }

    $fp = 7;
    $ppp = 9;

    if ( $query->is_paged ) {
        $offset = $fp + ( ($query->query_vars['paged'] - 2) * $ppp );
        $query->set('offset', $offset );
        $query->set('posts_per_page', $ppp );

    } else {
        $query->set('posts_per_page', $fp );
    }

}

add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {

    $fp = 7;
    $ppp = 9;

    if ( $query->is_home() ) {
        if ( $query->is_paged ) {
            return ( $found_posts + ( $ppp - $fp ) );
        }
    }
    return $found_posts;
}

Leave a Comment