scriptygoddess

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 :)

22 Responses to "WordPress Pagination Woes (solved? I hope?)"

1 | Brian Feister

March 1st, 2011 at 12:34 pm

Avatar

Thank you so much for posting this! It's been killing me as well! I'm not sure how familiar you are with the loop (seems like you are VERY familiar). I'm setting up my custom query differently than you but I'm experiencing the same problem (only page 1 of the query is displaying when clicking the nav links).

Here is the PHP for my query:

query(array(
'category_name' => 'classes',
'meta_key' => '_date_compare',
'meta_compare' => '>=',
'meta_value' => $current_date,
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page' => 10,
'paged' => $paged
));
if ($wp_query->have_posts()) : while ($wp_query->have_posts()) : $wp_query->the_post(); ?>

2 | Brian Feister

March 1st, 2011 at 12:35 pm

Avatar

Sorry, accidentally posted before finishing my comment. Anyway, do you know how the stuff you learned outlined in this post would apply to this very different loop? Here is that loop in action: http://hannahnour.co/classes

3 | Jennifer

March 1st, 2011 at 1:34 pm

Avatar

Are calling
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
before that? (You should)

4 | Brian Feister

March 1st, 2011 at 1:48 pm

Avatar

Hmmm… unfortunately, I already had that… no luck :( Obviously my query is VERY custom, it gets events in chronological order and is connected with a very complex date module that I authored with another developer.

5 | Jennifer

March 1st, 2011 at 1:50 pm

Avatar

And this isn't being used as a homepage template? It's hard to guess without seeing the rest of the code on the page… (it may be that you need to call wp_reset_query() too…) The fact that the query is custom shouldn't matter. I've got pagination working with custom queries, custom select queries…it's probably being affected by something else on the page…

6 | Brian Feister

March 1st, 2011 at 2:04 pm

Avatar

Ahhhh! You're right about wp_reset_query() … I probably needed that in there. I've added it and still no dice.

7 | Jennifer

March 1st, 2011 at 2:06 pm

Avatar

Can you post the full code on the page in pastebin and then either link it here or email. I will try to help.. scripty at this domain dot com

8 | Brian Feister

March 1st, 2011 at 2:08 pm

Avatar

This was the only way I could think of to quickly share the PHP with you: http://jsfiddle.net/25dy7/

9 | Jennifer

March 1st, 2011 at 4:06 pm

Avatar

Move
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
ABOVE
$wp_query = new WP_Query();

10 | Brian Feister

March 1st, 2011 at 4:20 pm

Avatar

YAY!!!! Thanks Jennifer, you're so scripty!

11 | Justin Roberts

July 26th, 2011 at 1:04 pm

Avatar

Thanks Jennifer… this did help but a 'how to' style post would be great on this one.

12 | Jennifer

July 26th, 2011 at 1:22 pm

Avatar

I will try. I have about a dozen new posts too that I need to get on this site, (they're all half-baked and in draft mode) but time to do so has been so limited. If there's a specific problem you're running into, let me know and I will try to help – but it will probably be a while before I can elaborate more on the pagination subject from a general point of view…

13 | Christopher

January 4th, 2012 at 9:26 am

Avatar

I have been trying to get pagination to work with a custom query on a custom template which uses a date filter to query posts from the last four months. The navigation link appears but always returns a not found error for the 2nd page.

I tried to implement the solution you offered, but am having the exact same results. Can you tell by looking if there is something obvious that I may have overlooked?

Here is a code snipet. http://pastebin.com/1Wjv7exa

Thanks,
–christopher

14 | Jennifer

January 4th, 2012 at 11:03 am

Avatar

Ok – I THINK I figured out your issue Christopher. I tested this on a local 3.3.1 install. So two things:

Issue 1) (This is more a note about my original post above – you weren't doing this…) The page vs paged issue may have changed. I could now only get the actual page number using:
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
even though I was running the test on the homepage. So that issue may now be null/void.

Issue 2) You need to get the page number BEFORE!!! you run that first "query_posts" (on your line 9 in that pastebin code)… otherwise – the page number will be based on that query_posts call which will always show the page number as "1"… So move try this instead and let me know how we do:
http://pastebin.com/ft1FiCan

The thing that probably makes this confusing is that in my example above – I pull that paged variable after my sql query – but I don't use query_posts to get the total number of posts – although that works fine.. the problem comes if you're trying to get original query vars… by pulling the total number of posts – you've just reset all those original query vars) :) so just grab those query vars BEFORE you change the page query…

Hopefully that makes sense. :)

15 | Christopher

January 4th, 2012 at 1:32 pm

Avatar

Jennifer,
Thank you for your response. I tried having the $paged value set first as you suggested and the result was the same. Here is the url where I am trying this.

http://theviolent.net/recent-works
http://theviolent.net/recent-works/page/2/ {produces the 404 error}

I tried using the $wpdb->get_results as you have in your example only to find that the "WHERE" filter was not being applied and was returning all posts.

I have tried to assign the $wp_query->found_posts and $wp_query->max_number_of_pages before the 1st query_posts call, between the two, and after the 2nd.
The following pastebin is my entire file with assignment after the 2nd query_posts.
http://pastebin.com/N1D5d3Z4

16 | Jennifer

January 5th, 2012 at 12:27 am

Avatar

Ok – I'm getting close. I can tell you WHY it's happening but don't have a solution yet. You're fighting against the default posts_per_page setting. So as a test – under "reading settings" – if you changed "Blog pages show at most" and set that to 9 – my guess is your next/previous links will work. (It did in my test).

I ran into a similar issue at one time trying to change the number of posts on a search results page. I used a solution from here to fix it:
http://wordpress.stackexchange.com/questions/21/show-a-different-number-of-posts-per-page-depending-on-context-e-g-homepage
But my first attempts at trying to get it to work on the category archive page, didn't work. Still need to test more – but maybe that gives you some more information about the problem…

17 | Jennifer

January 5th, 2012 at 1:14 am

Avatar

Ok – here's what I have working for me. You'll have to use that function to change the pre_get_posts value on archive pages… like this:
http://pastebin.com/ifLpC6rt
(that goes in your functions file)
This is so that you don't get that 404 – WordPress will throw the 404 before running your query and seeing that you actually changed the number of posts per page…
Then you have to use a custom select query for the posts (otherwise what we did above to force the change in posts_per_page will override any "posts_per_page" setting we put in query_posts…
http://pastebin.com/ux7ZS7LK
(then change "endwhile" to "endforeach"…

hope that makes sense..

18 | Christopher

January 5th, 2012 at 8:58 am

Avatar

Thank you again, Jennifer. I tried all that you suggested to no avail. After I made the changes, not even the first page pulled any results. It too pulled the 404 error.

I decided to change the category structure so that my recent-works category was now the top category over all my art work. I put all other art categories under it. Now I no longer have to build a custom query, rather all I have to do is filter for the last 120 days.

Thank you for all your help. If you would like, please browse through my fine art pieces, and I will gladly send you one for your service. Email me the title you want along with your mailing address, and I will send it out to you.

19 | Jennifer

January 5th, 2012 at 10:23 am

Avatar

Hi Christopher, always hard to bug test stuff like that remotely. Sorry those didn't help. Glad you found a solution though :)

20 | Christopher

January 5th, 2012 at 12:27 pm

Avatar

Yeah, it is indeed hard to do. And something remains elusive about why the pagination never worked. I tried everything I could find. Regardless, I do appreciate the time you put in, and ultimately I think it was this dialog which sparked the thought to restructure the categories.

And please do select one of my fine art pieces you like, and I will gladly send it your way. Thanks again.

21 | J

March 14th, 2012 at 10:50 am

Avatar

Thank you! Wasted fruitless hours.

just changed "page" to "paged" and suddenly page 2 really displayed page 2, not just the same darned page.

Thank you thank you!

22 | Antonio

June 10th, 2012 at 3:08 pm

Avatar

I've been trying to get pagination with custom query based on next gallery album feature.
My goal is to show all album , without create page with shortcode. I'd like to fetch all the information from DB and update the page.
I've tried this in my homepage

$album_id = $wpdb->get_results('SELECT id, name FROM wp_ngg_album ORDER BY id DESC');
if($album_id):
global $album;
foreach($album_id as $album):

$footeralbum = '[album='.$album->id .',compact]';
$footeralbum = apply_filters('the_content', $footeralbum );
?>

<?

endforeach;
endif;

but I cannot work pagination issue out.
Could you help me please?
Thank you very much

Featured Sponsors

Genesis Framework for WordPress

Advertise Here


  • Scott: Just moved changed the site URL as WP's installed in a subfolder. Cookie clearance worked for me. Thanks!
  • Stephen Lareau: Hi great blog thanks. Just thought I would add that it helps to put target = like this:1-800-555-1212 and
  • Cord Blomquist: Jennifer, you may want to check out tp2wp.com, a new service my company just launched that converts TypePad and Movable Type export files into WordPre

About


Advertisements