Paging and Custom WordPress Loops 29comments
Thanks for visiting! If you're new here, you may want to subscribe to our RSS feed. This blog posts regular Wordpress news, updates of themes, plugins, ideas, hacks, quick fixes and everything about blogging, especially about Wordpress. Go ahead, subscribe to our feed! You can also receive updates from this blog via email.
Last week I published two articles using custom loops. The first was about how to create a custom loop. The second was how to retrieve posts based on custom fields. In both articles, several readers commented that they would like to see paging and have it explained.
I’d like to thank Aaron Harun from Anthology of Ideas for supplying the code used in this post.
Paging, and why it doesn’t work with WP_Query
The paging magic happens in a file called ‘link-template.php‘ in the ‘wp-includes‘ folder.
Most themes have basic paging built in, with the help of two functions: next_posts_link and previous_posts_link.
These functions, as well as several others, make use of a global variable called $wp_query. This variable is actually an instance of the WP_Query object. However, when we create our own instantiation of WP_Query, we don’t have this global variable $wp_query, which is why paging will not work.
How to make paging work with a custom loop
As Aaron mentioned, the paging functions rely on a global variable called $wp_query. The “fix” is to trick WordPress into using the global $wp_query variable when using our own custom loops.
In the example below, I’ll show how to display the last five recent articles with our own custom loop with paging intact.
<h3>Recent Articles</h3> <ul> <?php $temp = $wp_query; $wp_query= null; $wp_query = new WP_Query(); $wp_query->query('showposts=5'.'&paged='.$paged); ?>
The first thing the code does (shown above) is create a temporary variable to hold a reference to global variable $wp_query. The wp_query variable is set to null, and we instantiate a new WP_Query object.
Notice in the query above that we have these parameters:
$wp_query->query('showposts=5'.'&paged='.$paged);
The paged portion of the query is critical in order to have paging.
From there, we can now do our own query and begin our custom loop.
<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?> <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li> <?php endwhile; ?> </ul>
Notice in the above code that the loop is initiated using the $wp_query variable. Since we are using $wp_query, paging should work.
Now it’s time to create our navigation links for paging:
<div class="navigation"> <div class="alignleft"><?php previous_posts_link('« Previous') ?></div> <div class="alignright"><?php next_posts_link('More »') ?></div> </div>
And finally, we assign the variable $wp_query back its original value using the $temp variable we set earlier.
<?php $wp_query = null; $wp_query = $temp;?>
The Full Code
<h3>Recent Articles</h3> <ul> <?php $temp = $wp_query; $wp_query= null; $wp_query = new WP_Query(); $wp_query->query('showposts=5'.'&paged='.$paged); ?> <?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?> <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li> <?php endwhile; ?> </ul> <div class="navigation"> <div class="alignleft"><?php previous_posts_link('« Previous') ?></div> <div class="alignright"><?php next_posts_link('More »') ?></div> </div> <?php $wp_query = null; $wp_query = $temp;?>
Additional Applications
The above technique can allow paging for custom loops. All you have to do to modify this is to use your own query parameters, and change the code within the custom loop.

Recent Articles Example
The above example is live at raproject.com under Recent Articles.
Conclusion
Paging is a powerful WordPress feature, and fortunately you can use it when defining your own custom loops.
The example I demonstrated was rather generic, but hopefully you’ll be able to apply it to your own custom loops where paging is necessary.
Please feel free to share your own examples or problem code in the comments. If you use code, please use something like pastebin since some code isn’t allowed in the comment section.










