I 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.
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.
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!
A couple of solutions present themselves:
Something like:
<?php global $paged; $this_page = $_GET['page']; $paged = $this_page; # Custom loop code ?> <?php next_posts_link(); ?> - <?php previous_posts_link(); ?>
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.