The next_posts_link() works only with original $wp_query

I’ve got custom template that I want to display paged blog posts. This is the beginning of my file:

$wp_query = new WP_Query($args);
    if($wp_query->have_posts()){
        while($wp_query->have_posts()){ $wp_query->the_post();
            //something...
    <?php next_posts_link('Older Entries'); ?>
    <?php previous_posts_link('Newer Entries'); ?>

It works fine – it displays OLDER and NEWER links when it should. On the first page it will display only a link to older entires. On the second page both to newer entries and yet older ones etc.

But I don’t want to overwrite current $wp_query… I want to use let’s say $wp_query2 for this loop. And the links don’t appear at all if I do this.

According to this: http://codex.wordpress.org/Function_Reference/next_posts_link they print a link to the prev/next set of posts within the current query. I assume that $wp_query2 isn’t my “CURRENT QUERY” but $wp_query always is. Can I change that somehow?

UPDATE:
Adding &paged=2 manually to the link causes it to correctly go to the next set of posts (next page) and on second, third etc. page previous_posts_link() works even if I use $wp_query2. So, I’m just missing next_posts_link() functionality on every page.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

next_posts_link and previous_posts_link use the global $wp_query.

function get_next_posts_link( $label = null, $max_page = 0 ) {
    global $paged, $wp_query;

http://core.trac.wordpress.org/browser/tags/3.5/wp-includes/link-template.php#L1523

That means you need to do something like this to get those to work correctly.

$orig_query = $wp_query;
$wp_query = new WP_Query($args);
// the rest of your code
$wp_query = $orig_query;

If you are done with $wp_query for that page load there is no reason to preserve it. It should be pretty easy to copy those core functions, modify them to accept a query parameter and create your own paging functions.

Method 2

Looking at the wordpress source, it looks like next_posts_link uses the global var $paged. My guess is that is only going to work for the primary loop.

A pretty good solution on how to make pagination work for secondary loops is here:
http://weblogtoolscollection.com/archives/2008/04/19/paging-and-custom-wordpress-loops/

It involves setting the paged query var explicitly in the query, like this:

<h3>Recent Articles</h3>
<ul>
<?php 
$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query();
$wp_query->query('showposts=5'.'&paged='.$paged);
?>

Hope that helps.

Method 3

I ran into the same issue. I have nested loops, so in the inner loop I am using $wp_query = new WP_Query($args); instead of the global WP_Query. The solution I used was to explicitely pass max_num_pages to the next_posts_link function. This has been mentioned in the comments by Andy Giesler as well.

Solution:

<?php  
  //outer loop  
    //some outer code
    //inner loop starts
      $inner_query = new WP_Query( 
                array('posts_per_page' => '4', 'paged' => get_query_var('paged')) 
            ); 
        // ...show all posts etc code  
      previous_posts_link( 'Older posts' ); 
      next_posts_link( 'Newer posts', $inner_query->max_num_pages ); //Note this
    //inner loop finishes
    //some other outer loop code  
  //outer loop finishes
?>

The reason we have to do this is that wordpress internally use global WP_query’s $max_page property, which if is undefined then the default will be $max_page = 0


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

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x