0

I'm working on a quite complex query, it has a different post count on the first page and on paginated pages, to achieve that I'm using offset and this seem to mess up the_posts_pagination.

Here's the code:

index.php

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
 //post content here...
<?php endwhile; endif; ?>

<?php
    the_posts_pagination( array(
        'mid_size'  => 2,
        'prev_text' => __( 'Prev', 'textdomain' ),
        'next_text' => __( 'Next', 'textdomain' ),
    ));
?>

functions.php

function my_offset( $query ) {
    $ppp = get_option( 'posts_per_page' );
    $first_page_ppp = 3;
    $paged = $query->query_vars[ 'paged' ];

    if( $query->is_home() && $query->is_main_query() ) {
        if( !is_paged() ) {

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

        } else {
            $paged_offset = $first_page_ppp + ( ($paged - 2) * $ppp );
            $query->set( 'offset', $paged_offset );

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

function my_offset_pagination( $found_posts, $query ) {
    $ppp = get_option( 'posts_per_page' );
    $first_page_ppp = 3;

    if( $query->is_home() && $query->is_main_query() ) {
        if( !is_paged() ) {

            return( $found_posts );

        } else {

            return( $found_posts - ($first_page_ppp - $ppp) );

        }
    }
    return $found_posts;
}
add_filter( 'found_posts', 'my_offset_pagination', 10, 2 );

The post per page is set to 5 in the reading settings, but the issue is there no matter what it's set to.

Now using this code the the_posts_pagination will show at least one extra empty page in the numbered pagination links. However if I go to the second page then the numbered pagination will display the correct number of max pages.

Any help is much appreciated

  • The problem is max_num_pages in inaccurate, but there's no filter for that. It's calculated with found_posts / posts_per_page, so I think your only option is to adjust what found_posts filter returns on the first page to make max_num_pages what it needs to be. – Milo Jan 6 '19 at 22:41
  • Thank you! So I believe I got something working. Instead of using the_post_pagination I switched to paginate_links, this lets me set the total number of pages. Then I basically did like this: $amount = $wp_query->found_posts; $totalpages = $amount - (3 - 5); echo paginate_links( array( ..... 'total' => $totalpages / 5 ) ); 3 is posts per page on the first page and 5 is on paginated pages. Does this seem like a crazy solution? – sebfck Jan 6 '19 at 23:58
  • I updated the post so you can see the code more easily – sebfck Jan 7 '19 at 0:04
  • Glad you got it working! You can add your solution as an answer and the system will let you accept it after a short wait period. – Milo Jan 7 '19 at 0:41
  • @sebfck can you post your answer as an answer instead of editing it into your question? Nobody can upvote it if you don't, and your can't mark it as the answer unless you post it – Tom J Nowell Jan 7 '19 at 1:04
0

Thanks to Milo I found something that's making it work as expected:

Changes made to index.php :

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
 //post content here...
<?php endwhile; endif; ?>

<?php
global $wp_query;

$big = 999999999; // need an unlikely integer
$amount = $wp_query->found_posts;
$totalpages = $amount - (3 - 5);

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'current' => max( 1, get_query_var('paged') ),
    'total' => $totalpages / 5
) );
?>

So I switched over to paginate_links which lets me set a total number of pages which I could calculate using the found_posts and 3(amount of posts on first page) and 5(amount of posts on paginated pages).

EDIT:

Found another better solution:

function my_offset_pagination( $found_posts, $query ) {
    $ppp = get_option( 'posts_per_page' );
    $first_page_ppp = 3;

    if( $query->is_home() && $query->is_main_query() ) {
        if( !is_paged() ) {

            return( $first_page_ppp + ( $found_posts - $first_page_ppp ) * $first_page_ppp / $ppp );

        } else {

            return( $found_posts - ($first_page_ppp - $ppp) );

        }
    }
    return $found_posts;
}
add_filter( 'found_posts', 'my_offset_pagination', 10, 2 );

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.