paginate_links() outputs extra empty pages on custom loop

I have a custom loop:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$works = new WP_Query('category_name=work&posts_per_page=9&paged=' . $paged); 

Pagination outputs 3 pages, on first there are 9 posts, which is also total number of posts, and on pages 2 and 3 there are no posts (there should be no pages if there are no posts on them, right?)

Read More

Here is my paginate_links():

<?php elseif ( $wp_query->max_num_pages > 1 && ( is_home() || is_archive() || is_search() || is_category() ) ) : // navigation links for home, archive, and search pages ?>

    <?php 
        global $wp_query;

    $big = 999999999;

    echo paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format' => '?paged=%#%',
        'prev_text' => '',
        'next_text' => '',
        'current' => max( 1, get_query_var('paged') ),
        'total' => $wp_query->max_num_pages
    ) );

    ?>

<?php endif; ?>

On default loop everything is fine.

Related posts

2 comments

  1. You use your custom WP_Query to query posts, but then in pagination you use global $wp_query variable, which contains different query.

    You should use your custom query variable $works in your pagination, or change global $wp_query variable before your pagination function call.

    Since you use universal function to output pagination, second method will be better/easier. Do it like this:

    global $wp_query;
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $works = new WP_Query('category_name=work&posts_per_page=9&paged=' . $paged);
    
    $original_query = $wp_query;  // store original query for later use
    $wp_query = $works;  // overwrite it with your custom query
    
    ... your code
    
    ... your pagination code
    
    $wp_query = $original_query;  // restore original query
    
  2. Just use your custom WP_Query/$works object to access the data in the paginate_links() arguments as well.

    paginate_links( array(
        'base'      => str_replace( 99999999, '%#%', esc_url( get_pagenum_link( 99999999 ) ) ),
        'format'    => '?paged=%#%',
        'prev_text' => '',
        'next_text' => '',
        'current'   => max( 1, $works->get( 'paged' ) ),
        'total'     => $works->max_num_pages
    ) );
    

Comments are closed.