11

I need to have a different amount of posts per page on the first page that on the other pages.

For example, this is what I need

  • Total posts: 6
  • First page: showing 3 posts
  • Following page: showing 2 posts per page

Here's my code:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$fp_limit = 3; // first page limit
$limit = 2; // following page limit
$offset = 0; // default offset

if( $paged == 1 ) {
    $limit = $fp_limit;
} else {
    $offset = $fp_limit + ( ($paged - 2) * $limit );
}

$args = array(
    'post_type' => 'my_post_type',
    'post_status' => 'publish',
    'offset' => $offset,
    'posts_per_page' => $limit,
    'caller_ get_ posts' => -1, // remove sticky post
    'paged' => $paged,
    'tax_query' => array(
        array(
            'taxonomy' => 'my_taxo',
            'field' => 'slug',
            'terms' => array('slug1', 'slug2', 'slug3')
        )
    )
);
$my_query = null;
$my_query = new WP_Query($args);

// basic loop
if( $my_query->have_posts() ) : 
while ($my_query->have_posts()) : $my_query->the_post();

...

endwhile; endif; // archive loop
if (function_exists('wp_pagenavi')){ wp_pagenavi( array( 'query' => $my_query ) ); }

wp_reset_query();

At first page in archive, this code assumes:

Well, 6 posts total and 3 posts per page. So I need 2 archive pages and the pagination I present to you is:

[1] [2]

However, any other page in archive the code assumes:

Well, 6 posts total and 2 posts per page. So I need 3 archive pages and the pagination I present to you is:

[1] [2] [3]

Need a little help to fix this.

  • If only I could tell WP_pagenavi how many posts at 1st page and the rest... – norixxx Jul 25 '14 at 9:59
  • Why exactly do you need to do it this way. Any particular reason – Pieter Goosen Jul 25 '14 at 10:06
  • Just my client's selfishness. I actually do not care if I use wp_pagenavi or not. Any other technique I can use? – norixxx Jul 25 '14 at 10:12
  • 2
    First off 'caller_ get_ posts' contains spaces and is not valid. Second, it's deprecated. Use ignore_sticky_posts instead. – kaiser Jul 25 '14 at 12:22
  • Your home page, is it a normal homepage or set as a front page – Pieter Goosen Jul 25 '14 at 12:48
20

EDIT - ANSWER REVISITED

I've being working on another solution which is actually better the original answer. This does not involve any custom query and I think for all purposes my original answer can be dropped but kept for informational purposes

I still believe you are on the homepage and will also treat this as such. So this is my new solution

STEP 1

Remove the custom query from the homepage and replace it with the default loop

<?php

        if ( have_posts() ) :
            // Start the Loop.
            while ( have_posts() ) : the_post();

                ///<---YOUR LOOP--->

            endwhile;

                //<---YOUR PAGINATION--->   

            else : 

                //NO POSTS FOUND OR SOMETHING   

            endif; 

    ?>

STEP 2

Use pre_get_posts to alter the main query to add your custom taxonomy to the main query to display on the home page.

STEP 3

Now, get the posts_per_page option set from the back end (which I assume is 2) and also set your offset which we are going to use. That will be 1 as you will need 3 posts on page one and 2 on the rest

$ppg = get_option('posts_per_page');
$offset = 1;

STEP 4

On page one, you'll need to add the offset to posts_per_page will add up to 3 to get your three posts on page one.

$query->set('posts_per_page', $offset + $ppp);

STEP 5

You must apply your offset to all subsequent pages, otherwise you will get a repetition of the last post of the page on the next page

$offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
$query->set('posts_per_page',$ppp);
$query->set('offset',$offset); 

STEP 6

Lastly, you need to subtract your offset from found_posts otherwise your pagination on the last page will be wrong and give you a 404 error as the last post will be missing due to the incorrect post count

NOTE: This piece of code broke pagination on the search page. This is now fixed, see the updated code

function homepage_offset_pagination( $found_posts, $query ) {
    $offset = 1;

    if( $query->is_home() && $query->is_main_query() ) {
        $found_posts = $found_posts - $offset;
    }
    return $found_posts;
}
add_filter( 'found_posts', 'homepage_offset_pagination', 10, 2 );

ALL TOGETHER

This is how your complete query will look like that should go into functions.php

function tax_and_offset_homepage( $query ) {
  if ($query->is_home() && $query->is_main_query() && !is_admin()) {
    $query->set( 'post_type', 'my_post_type' );
    $query->set( 'post_status', 'publish' );
    $query->set( 'ignore_sticky_posts', '-1' );
    $tax_query = array(
        array(
            'taxonomy' => 'my_taxo',
            'field' => 'slug',
            'terms' => array('slug1', 'slug2', 'slug3')
        )
    );
    $query->set( 'tax_query', $tax_query );
    $ppp = get_option('posts_per_page');
    $offset = 1;
    if (!$query->is_paged()) {
      $query->set('posts_per_page',$offset + $ppp);
    } else {
      $offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
      $query->set('posts_per_page',$ppp);
      $query->set('offset',$offset);
    }
  }
}
add_action('pre_get_posts','tax_and_offset_homepage');

function homepage_offset_pagination( $found_posts, $query ) {
    $offset = 1;

    if( $query->is_home() && $query->is_main_query() ) {
        $found_posts = $found_posts - $offset;
    }
    return $found_posts;
}
add_filter( 'found_posts', 'homepage_offset_pagination', 10, 2 );
3

I know this is from 1000 years ago, but another solution for anyone else looking for this solution while using a custom query, here is how to do it. In this example the 1st page needed 10 posts and every subsequent page needs 9.

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if( $paged == 1 ) {
   $limit = 10;
} else {
   $limit = 9;
}

and then in the array use this:

'posts_per_page' => $limit,

Now you're good to go.

  • 1
    This won't work. With this you will have post #10 be displayed twice. Since when going on the second page it will "think" that the first page also had 9 posts displayed and therefore will start showing post #10 although it already got displayed on the first page. – leymannx May 9 at 6:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.