4/19/2008 ↓

Paging and Custom WordPress Loops

Author: Ronald Huereca Category: HOW-TO, WordPress Hack

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('&laquo; Previous') ?></div>
  <div class="alignright"><?php next_posts_link('More &raquo;') ?></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('&laquo; Previous') ?></div>
  <div class="alignright"><?php next_posts_link('More &raquo;') ?></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-screenshot.jpeg
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.

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5 out of 5)
Loading ... Loading ...
Sphere: Related Content | stumbleit |
Translate to German Translate to Spanish Translate to French Translate to Italian Translate to Portuguese Translate to Japanese Translate to Korean Translate to Russian Translate to Chinese

Latest Videos

24 Comments | Leave a comment | Comments RSS

  1. My blog has nothing with pages in the loop but its a good example of the category/gallery function that has become available via 2.5. An example of this can also be seen on Matt’s page…

    Neil (5 comments.) — 04/19/2008 @ 10:45 pm
  2. I’m not as familiar with php (and WordPress) as with c++, but why not just use a different name for your new $wp_query instance, say $my_query, and leave the existing one as is?

    Carson (16 comments.) — 04/20/2008 @ 9:31 am
  3. @Carson - That’s what I’ve done in the past. I don’t really understand why you would need to use $wp_query, when you can use a different name. But it seems that everyone has a different way of doing it. :)

    Darryl (6 comments.) — 04/20/2008 @ 10:02 am
  4. @Carson and Darryl,

    Certain functions specifically call the $wp_query directly and don’t allow you to change the variable name. You can use $my_query, but for those functions that call $wp_query, they won’t work or, even worse, they will refer to the original $wp_query.

    Aaron (32 comments.) — 04/20/2008 @ 12:35 pm
  5. @Aaron: I see. I understand that “the loop” is supposed to be a convenience for template builders. But for me it has been more like a millstone around my neck. Then I discovered that some (maybe all?) of the functions that only work in the loop have non-loop versions. I’m sure there is a reason for all this but I’ve found that when work-arounds abound there is usually an underlying design flaw. Let me add though that in my career as a coder I never had to satisfy millions of users — at most dozens.

    Carson (16 comments.) — 04/20/2008 @ 1:21 pm
  6. This was helpful, I have a bunch of static pages in the loop (I added WP on top of a mostly static site).

    tinkertim (1 comments.) — 04/20/2008 @ 1:24 pm
  7. @Carson,
    Yes, the loop functions typically use global variables and also call other non-loop functions. The issue here is paging, and using something other than wp_query (a global variable) will break paging.

    The other article I wrote (mentioned at the very beginning) covers custom loops that don’t require paging.

    Ronald Huereca (48 comments.) — 04/20/2008 @ 2:11 pm
  8. @Ronald: Your “how to” posts have been quite helpful. I have them all bookmarked. Thank you.

    Carson (16 comments.) — 04/20/2008 @ 8:11 pm
  9. @Carson,
    Thanks a lot! I hope they can help you out. If there’s anything else you’d like to know, please let me know. This post was written as a direct result of reader questions.
    Ronald Huereca (48 comments.) — 04/20/2008 @ 9:56 pm
  10. Nice post(s) on loops.

    You can take this a step further and add a category tag to the query to loop category based posts into section to make widgets such as asides or side blogs.

    In 2.3 and up you can use:

    $wp_query->query('cat=X&showposts=5'.'&paged='.$paged);

    Where “X” is the number of the category of interest.

    hso (8 comments.) — 04/20/2008 @ 10:41 pm
  11. @hso,
    Yes, there are a very wide variety of applications. Using the query_posts parameters, and even filters, the possibilities seem endless.

    Thanks for sharing your technique.

    Ronald Huereca (48 comments.) — 04/20/2008 @ 11:01 pm
  12. [...] están pensando en agregar cositas nuevas a sus themes wordpress, acabo de ver este agradable tip para generar paginación con nuestros articulos [...]

  13. [...] Paging and Custom WordPress Loops (tags: wordpress) [...]

  14. [...] Paging and Custom WordPress Loops I stumbled on the right combination here by accident… useful info for anyone trying to deal with multiple “loops” (tags: linklog wordpress wp) [...]

  15. [...] Paging and Custom WordPress Loops — I stumbled on the right combination here by accident… useful info for anyone trying to deal with multiple “loops” [...]

  16. I implemented your example code on my locally hosted test blog and found that it worked well except for one thing. When I click the More link it advances the actual recently posted articles as well as the new list of recently posted article titles. I looked at your implementation at raproject and saw that it doesn’t do this. Any idea why mine behaves that way?

    Carson (16 comments.) — 04/22/2008 @ 11:40 am
  17. [...] Paging and Custom WordPress Loops - Za chví?u zo m?a bude programátor Ale ke? m?a to tak baví a skladanie kúskov kódov je ako Lego. No vždy treba ma? na pamäti, že profesionálne nasadenie si žiada profesionálny prístup. Amatérom sú pravidelne skryté na prvý poh?ad nevidite?né bezpe?nostné súvislosti. No a naopak, také to domácke programovanie je pre nás vedúcich projektov, zadávate?ov neocenite?né v jednej zásadnej oblasti. Vieme, že to ide zrealizova?. [...]

  18. [...] Weblog Tools Collection pubblica un interessante post che illustra come integrare la paginazione nei loop di WordPress. [...]

  19. [...] Weblog Tools Collection made a great post that shows how to use pagination in the WordPress loops. [...]

  20. [...] están pensando en agregar cositas nuevas a sus themes wordpress, acabo de ver este agradable tip para generar paginación con nuestros articulos [...]

    Extremisimo — 04/25/2008 @ 10:56 pm
  21. Great stuff, just what I needed for a Wordpress project.

    Paul @ Web Design Ireland (1 comments.) — 05/11/2008 @ 12:24 pm
  22. How would you use this with an offset? For example ‘&offset=1′, so it doesn’t show the most recent 1 post. I tried usuing it as usual and it broke the navigation control

    John Kolbert (14 comments.) — 05/13/2008 @ 1:38 am
  23. @John,
    That’s odd. I haven’t tried an offset, but I know what you mean. Let me play around a bit and see if I can figure out what’s wrong.
    Ronald Huereca (48 comments.) — 05/13/2008 @ 1:47 am
  24. Thanks Ronald, I look forward to seeing what you can come up with!

    John Kolbert (14 comments.) — 05/14/2008 @ 1:59 am

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(required)

(required, will not be published)


S2