$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>pagination - Using the_posts_pagination with offset adds extra empty page|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

pagination - Using the_posts_pagination with offset adds extra empty page

matteradmin10PV0评论

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

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

Share Improve this question edited Jan 7, 2019 at 2:16 sebfck asked Jan 6, 2019 at 22:04 sebfcksebfck 1051 silver badge6 bronze badges 6
  • 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 Commented Jan 6, 2019 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 Commented Jan 6, 2019 at 23:58
  • I updated the post so you can see the code more easily – sebfck Commented Jan 7, 2019 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 Commented Jan 7, 2019 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 Commented Jan 7, 2019 at 1:04
 |  Show 1 more comment

1 Answer 1

Reset to default 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 );
Post a comment

comment list (0)

  1. No comments so far