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.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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 );
Method 2
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.
Method 3
Kiel was really close. I needed 3 on the front page, 12 on subsequent pages, this is where I landed:
<?php
$paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1;
$current_cat = get_category($cat);
$limit = 12; // Set the posts limit on all the pages but the first
$offset = 3; // Set this to the number of posts on the first page
if( $paged == 1 ) {
$offset = 0; // No offset on the first page
$limit = 3; // Number of posts on the front
} else {
$offset = (($paged - 2) * $limit) + $offset; // The magic happens here
}
$args = array(
'post_type' => 'post',
'category_name' => $current_cat->slug,
'paged' => $paged,
'offset' => $offset,
'posts_per_page' => $limit,
'orderby' => 'date',
'order' => 'DESC',
);
?>
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0