Another one of these paging errors you see here so often. I searched high and low for a fix but have come up with nada so far.

I am paging CPT results using my archive-{$post_type}.php template and getting an incomplete return of posts. I have set posts_per_page to 8, and am return 3 pages to get 24 results. There are 27 posts, so I am missing 3 (ie. paging falls short of showing last 3 posts).

Here's my template file (HTML stripped for clarity):

<?php   /* SET UP */


        // Selected team member
        $team_member_id = $_GET['member'];

        // Top post by menu order
        $top_post = get_posts('post_type=team&numberposts=1&orderby=menu_order&order=ASC');
        $top_post_id = $top_post[0]->ID;

        // Set $current_team_member_id
        if ($team_member_id) {
            $current_team_member_id = $team_member_id;
        } else {
            $current_team_member_id = $top_post_id;


<?php   /* MENU */

        // Paging
        $page = (get_query_var('paged')) ? get_query_var('paged') : 1;

        // Args
        $args = array(
            'post_type'=> 'team',
            'posts_per_page' => '8',
            'paged' => $page,
            'orderby' => 'menu_order',
            'order' => 'ASC',

        // New instance of WP_Query
        $loop = new WP_Query($args);

        if ($loop->have_posts()) :


<?php next_posts_link('<span class="nextpost">Next</span>' ); ?>
<?php previous_posts_link('<span class="previouspost">Back</span>' ); ?>

<?php while ($loop->have_posts()) : $loop->the_post(); ?>

<?php   $post_id = get_the_ID();
        $postclass =  '';

        if( $current_team_member_id == $post_id ) {

            $postclass = 'current'; 

        } elseif ( $top_post_id == $post_id && $current_team_member_id == NULL) {

            $postclass = 'current'; 

        } else {

            $postclass =  'post'; 


        $url = get_bloginfo('url').'?post_type=team&member='.$post_id.'&paged='.$page; 


<a id="team-member-<?php print $post_id; ?>" href="<?php print $url; ?>" class="<?php print $postclass; ?> <?php print $top_post_id; ?>"><?php the_title() ;?></a><br>
<?php echo get_post_meta( $post->ID, '_exit_member_metabox_pos', true ); ?>

<?php endwhile; ?>

<?php   /* MEMBER PROFILE */

        $current_team_member_post = get_post($current_team_member_id ); 


<?php echo $current_team_member_post->post_title; ?>
<?php echo get_post_meta( $current_team_member_id , '_exit_member_metabox_pos', true ); ?>
<?php the_content(); ?>
<?php echo get_the_post_thumbnail($current_team_member_id, 'pic-third'); ?>

<?php else: ?>

    <p>Sorry, but this content is not available.</p>

<?php endif; ?>

What am I doing wrong? What's missing?

2 Answers 2


I think next_posts_link() is using the global $wp_query to determine pagination, but you've created a new query here. Try passing max_num_pages from your $loop query to it:

next_posts_link( '<span class="nextpost">Next</span>', $loop->max_num_pages );
  • I stumbled on the most absurd of solutions!!!! I went to wp-admin>settings>reading and changed the value of "blogs show at most" to a number smaller than that set in the query. I set it to 1. Hackish? Yes! Illogical? Yes!!!!!!! I will answer my own question once I have permission
    – Niels
    Commented Oct 19, 2011 at 4:49
  • @Niels Oeltjen - are you sure you don't now have too many pages? I think you may just be masking the underlying problem. another solution would be to call query_posts( $args ); rather than creating a new WP_Query, since you don't appear to be using the original query for the page, then the globals will be correctly set in relation to your query.
    – Milo
    Commented Oct 19, 2011 at 5:15
  • Yes, you are right about the extra page. I had in fact reverted to query_posts(); which seemed to fix it.
    – Niels
    Commented Oct 19, 2011 at 22:56

As per @Milo's comments the solution lies in using query_posts(); in this instance, instead of WP_Query.

The fix needed three changes:

  1. Go to wp-admin > settings > reading and change the value of "blogs show at most" to a number smaller than that set in the query. I set it to 1.

  2. Use query_posts($args); instead of $loop = new WP_Query($args);. I had started with this, but resorted to WP_Query as a workaround. As @Milo mentions this is not really necessary as only one loop is called in the template.

  3. As the number of queries has been edited in wp-admin, any other loops in the theme need to be prepended by query_posts to set the number of posts retrieved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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