Broken pagination

The question:

Well I’m here again with almost the same problem as I had in this post three weeks ago, but let me explain what has happened since then:

I was originally using one loop to display the most recent sticky post at the top of the front page, then a second loop to display every other post (except for all other stickies). Here’s my code as it stands now:

// first loop to display only my single, MOST RECENT sticky post
$sticky = get_option('sticky_posts');
$wp_query = new WP_Query(array('post__in' => $sticky, 'caller_get_posts' => 1, 'orderby' => ID, 'showposts' => 1)); ?>
<?php while (have_posts()) : the_post(); ?>
    <!-- loop code -->
<?php endwhile; wp_reset_query(); ?>

// second loop to display every other post, excluding sticky posts
<?php query_posts(array('post__not_in' => get_option('sticky_posts'))); // exclude all sticky posts ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    <!-- loop code -->
<?php endif; wp_reset_query(); ?>

What is happening here is perfect…for the front page only. I get my nice single/most-recent sticky post at the very top, followed by another 5 posts. Unfortunately, if I page over to the 2nd, 3rd, 4th, etc pages – all I see are the same 5 posts that were under the sticky post on the front page!

I’m quite new with the concept of multiple loops, so I could really use a hand here!

Thank you in advance 🙂

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I see a few issues that are probably contributing to your issue:

  1. Only ever use query_posts() to modify the primary Loop.
  2. The caller_get_posts parameter has been deprecated, in favor of ignore_sticky_posts
  3. The $wp_query variable is a defined global. Using it outside of its intended use may cause unintended circumstances.

So, first, you need to determine which is your primary Loop. I will assume this to be the second loop.

Second, come up with a unique, descriptive name for your secondary loop (i.e. your first loop), such as $most_recent_sticky_post.

That should leave you with:

<?php
// Get IDs of sticky posts
$sticky = get_option('sticky_posts');
// first loop to display only my single, 
// MOST RECENT sticky post
$most_recent_sticky_post = new WP_Query( array( 
    // Only sticky posts
    'post__in' => $sticky, 
    // Treat them as sticky posts
    'ignore_sticky_posts' => 0, 
    // Order by ID
    'orderby' => ID, 
    // Get only the one most recent
    'showposts' => 1
) );
while ( $most_recent_sticky_post->have_posts() ) : $most_recent_sticky_post->the_post(); ?>
    <!-- loop code -->
<?php endwhile; wp_reset_query(); ?>

// second loop to display every other post, 
// excluding sticky posts
<?php 
query_posts( array( 
    // exclude all sticky posts
    'post__not_in' => get_option( 'sticky_posts' ) 
) );  
if (have_posts()) : while (have_posts()) : the_post(); ?>
    <!-- loop code -->
<?php endif; wp_reset_query(); ?>

Now, since you’re no longer stomping on $wp_query, your pagination should work properly.

Edit

Okay, other things:

  1. The showposts parameter is also deprecated. Use post_per_page instead.
  2. Let’s try doing a merge of query variables for your primary loop.

e.g.:

// Define custom query args
$custom_query_args = array( 
    // exclude all sticky posts
    'post__not_in' => get_option( 'sticky_posts' ) 
);  
// globalize $wp_query
global $wp_query;
// Merge custom args with default query args
$merged_query_args = array_merge( $wp_query->query, $custom_query_args );
// process the query
query_posts( $merged_query_args );

I don’t know that this will make a difference, but I prefer to modify the default query using this method.

  1. If that still doesn’t work, then force query_posts() to remember that it’s supposed to use paging. Add 'paged' => get_query_var('paged') to your $custom_query_args array:

e.g.

  // Define custom query args
  $custom_query_args = array( 
      // exclude all sticky posts
      'post__not_in' => get_option( 'sticky_posts' ),
      // don't forget to paginate!
      'paged' => get_query_var('paged')
  );  

Where does that get us?

Method 2

Shouldn’t you be using paging parameters in your WP_Query

 $posts = new WP_Query( array( /*your args here*/, 'paged' => get_query_var( 'page' ) ) );

It could be get_query_var( ‘paged’ ) depending on WP version I believe.

WP_Query pagination parameters here


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment