WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?)

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 ?>

        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.

share|improve this question
Try using query_posts instead of WP_Query. That might solve issue. But I won't recommend so because of these factors. – Rohit Pande Jun 26 '13 at 9:05
up vote 2 down vote accepted

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
share|improve this answer
exactly what I needed... thank you! – Bojana Šekeljić Jun 26 '13 at 9:23
actually now, some of my footer content is gone on page with the custom loop... it is conflicting with do_shortcode() function. any thoughts? thanks – Bojana Šekeljić Jun 26 '13 at 9:33
Don't know what is in your footer and how is it done. Using wp_reset_query and wp_reset_postdata functions should help. – Krzysiek Dróżdż Jun 26 '13 at 9:35
ah right :)... I am panicing a bit, can't think straight... thank you very much for your help! – Bojana Šekeljić Jun 26 '13 at 9:38
Your code is magic! Thankfully I stumbled upon your answer as paginate_links in codec does not have enough info on custom queries and custom archive pages. – alds Aug 26 '15 at 7:38

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
) );
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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