Oikos Oikos
Search
Tech Notes: WordPress Pagination in Custom Loops

Photo of Older Posts LinkI was implementing AJAX-based pagination on the Stop AIDS Campaign homepage yesterday and came across an interesting thing with WordPress pagination links in custom loops.

The Problem

I had a custom loop that was on the homepage, which is printed using the special front-page.php page template. I was picking up the “page” query var in my loop to print the right items, and then trying to use next_posts_link() and previous_posts_link() to print, well, the links that you’d think those functions printed from within a WordPress loop. (Remember that these might work backwards to what you expect – see the excellent Digging Into WordPress article for more)

But they weren’t working, always printing just the “next posts” link from the first page, regardless of what page I was actually on.

Technical Details

The problem is that next_posts_link() and previous_posts_link() use a global variable $paged to work out what page you’re on (see code from v3.3.1 here), and $paged is not set set on a per-loop basis, is only set during the initial page redirect (see code in canonical.php).

So, when I do the query_posts() call for my custom loop, I’m not setting the $paged, variable. In fact, because I’m working inside a page template rather than an archive/index type template, I don’t think $paged is set at all!

Solutions:

A couple of solutions present themselves:

Set $paged manually for your loop

Something like:

<?php
  global $paged;
  $this_page = $_GET['page'];
  $paged = $this_page;

  # Custom loop code 
?>

<?php next_posts_link(); ?> - <?php previous_posts_link(); ?>

Do Your Own Thing

In the end this is what I did. next_posts_link() and previous_posts_link() didn’t give me enough control to be able to do the AJAX as I wanted, so I just hand-rolled a solution.  It looks kinda link this:

<div id="latest-news-nav">
  <?php
    // Set up next and prev links
    $this_page = $latest_news_query->get('paged');
    $max_page = $latest_news_query->max_num_pages;
    if ($this_page > 1) {
      printf('<a class="latest-news-newer" href="%s">Newer posts</a>', get_bloginfo('wpurl') . '/wp-admin/admin-ajax.php?action=latest_news&page=' . ($this_page - 1) );
    }
    if ($this_page < $max_page) {
      printf('<a class="latest-news-older" href="%s">Older posts</a>', get_bloginfo('url') . '/wp-admin/admin-ajax.php?action=latest_news&page=' . ($this_page + 1) );
    }
  ?>
</div>

I won’t go into how the AJAX works here – that’s the topic of another post, or possibly the next Oikos plugin.

Anyway, hope that helped someone.