Question

How do you set the posts_per_page query setting so that a different number of posts are displayed on the first of the paginated pages (of home, archive, search, etc.) and the rest of them?

For example, say I'd like to display 10 posts on the first of the paginated pages of category archives, and 15 on the rest of them. How do I do it?

This works:

function itsme_category_offset( $query ) {
  if( $query->is_category() && $query->is_main_query() ) {

    if( !$query->is_paged() ) {

      $query->set( 'posts_per_page', 10 );

    } else {

      $query->set( 'offset', 10 );
      $query->set( 'posts_per_page', 15 );

    }
  }
}
add_action( 'pre_get_posts', 'itsme_category_offset' );

But...

According to the Codex entry for WP_Query() pagination parameters:

offset (int) - number of post to displace or pass over. Warning: Setting the offset parameter overrides/ignores the paged parameter and breaks pagination

And according to the linked Codex entry for a workaround:

Specifying hard-coded offsets in queries can and will break pagination since offset is used by WordPress internally to calculate and handle pagination.

The indicated workaround uses a function that hooks into found_posts filter and establishes the offset. It supposes that I should do something like this:

function itsme_category_offset( $query ) {
  if( $query->is_category() && $query->is_main_query() ) {
    $paged = get_query_var( 'paged' );

    if( 0 == $paged ) {

      $query->set( 'posts_per_page', 10 );

    } else {

      $offset = 10 + ( ($paged - 2) * 15 );
      $query->set( 'offset', $offset );
      $query->set( 'posts_per_page', 15 );

    }
  }
}
add_action( 'pre_get_posts', 'itsme_category_offset' );

function itsme_adjust_category_offset_pagination( $found_posts, $query ) {
  $paged = get_query_var( 'paged' );
  if( $query->is_category() && $query->is_main_query() ) {
    if( 0 == $paged ) {

      $offset = 0;

    } else {

      $offset = 10 + ( ($paged - 2) * 15 );

    }

    return $found_posts - $offset;
  }
}
add_filter( 'found_posts', 'itsme_adjust_category_offset_pagination' );

Since my simpler function works already, is the Codex warning still correct? (i.e. should I do it as shown in the second code block?) Was this offset/pagination issue fixed in a recent version of WordPress? And if so: how?

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top