23 Feb, 2011
WordPress Pagination Woes (solved? I hope?)
Posted by: Jennifer In: WordPress|WordPress: Lessons Learned
For awhile now, I've run into pagination problems when doing custom templates and custom queries. I think I'm finally starting to figure out all the little nuances. For starters, in most cases this will get pagination working on a custom template with a standard query_posts():
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
That's the key to getting the next_posts_link() and previous_posts_link() working. So you have this on your custom template:
$paged = get_query_var( 'page' ) ? get_query_var( 'page' ) : 1;
$args = array(
'post_type'=>'my_custom_post_type',
'paged' => $paged
);
query_posts( $args );
And then this will paginate the content:
next_posts_link('Older Posts');
previous_posts_link('Newer Posts');
If you need to make use of any information regarding the current page (not referencing your custom query – then you'll probably need this after you loop through your custom query:
wp_reset_query();
However, in my most recent use, get_query_var('paged') always returned "1" no matter what page I was on. After much searching, I finally found out, if you're using a custom template for the homepage, and you're using a custom query for the posts displayed on that page, then you have to do this instead:
$paged = (get_query_var('page')) ? get_query_var('page') : 1;
(note the use of "page" vs. "paged")
Why these two values are different, I'm not sure, but they are… and this was the only thing that got pagination working on the custom template for the homepage.
Then there was another wrinkle I discovered. If you're doing a custom select query to get posts – then this forum post has this important code to get the pagination working – as there are some variables that do not get populated with a custom select query, and are needed for pagination:
$total = "your custom select query goes here, but without LIMIT and OFFSET, so the total number of posts that match the query can be counted";
$totalposts = $wpdb->get_results($total, OBJECT);
$ppp = intval(get_query_var('posts_per_page'));
$wp_query->found_posts = count($totalposts);
$wp_query->max_num_pages = ceil($wp_query->found_posts / $ppp);
$paged = (get_query_var('page')) ? get_query_var('page') : 1;
// or use the below for custom select queries used on a homepage custom template
//$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$offset = ($paged-1) * $ppp;
$wp_query->request = "your query again, but with the LIMIT and OFFSET as follows: LIMIT $ppp OFFSET $offset";
$pageposts = $wpdb->get_results($wp_query->request, OBJECT);
Then, after you foreach loop – you can use the next_posts_link(), previous_posts_link() to show the pagination…
Another tidbit I discovered along with this… when doing a custom select query loop, you'll have something similar to this:
foreach ($pageposts as $post):
setup_postdata($post);
... stuff for your template like <h1><?php the_title(); ?>
etc...
endforeach;
If you use a different variable name other than "$post" in that foreach call – it's not going to work 100% right. Tags like the_title() will display the title for the current page (that's using the custom template) not the page/post within your custom loop.
I realize this is not an in-depth how-to type post, still I hope this information helps someone struggling with the same things I was