Reader John writes in:
How does one use paging with an offset? Doing so breaks the navigation controls.
The problem with using an offset in a query is that WordPress ignores any reference to paging. In other words, you can use an offset and paging, but not both together.
This can be solved by tapping into the post_limits filter.
Step 1: Add the ‘my_post_limit’ Function
The my_post_limit function is what the post_limits filter will use to update the standard loop query.
We’ll use the function to use paging and offsets together. This function should be placed in your theme’s functions.php file.
function my_post_limit($limit) { global $paged, $myOffset; if (empty($paged)) { $paged = 1; } $postperpage = intval(get_option('posts_per_page')); $pgstrt = ((intval($paged) -1) * $postperpage) + $myOffset . ', '; $limit = 'LIMIT '.$pgstrt.$postperpage; return $limit; } //end function my_post_limit
Step 2: Add the Filter Reference
<?php add_filter('post_limits', 'my_post_limit'); ?> <div id="recent"> <h3>Recent Articles</h3>
In the above code, I add a filter for post_limits, which will call the my_post_limit function mentioned in Step 1.
Step 3: Start Your Loop
In this loop, we’ll be declaring a global variable called $myOffset. This will be the offset we’d like to have and is used by the my_post_limit function.
<ul> <?php global $myOffset; $myOffset = 1; $temp = $wp_query; $wp_query= null; $wp_query = new WP_Query(); $wp_query->query('offset='.$myOffset.'&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>
Step 4: Enable Navigation
We’re just adding the standard next/previous links at the end of the loop.
<div class="navigation"> <div class="alignleft"><?php previous_posts_link('« Previous') ?></div> <div class="alignright"><?php next_posts_link('More »') ?></div> </div> </div>
Step 5: Remove the Filter
In this step, we’ll be removing the post_limits filter and assigning the query back to its original value thanks to a temporary placeholder.
<?php $wp_query = null; $wp_query = $temp;?> <?php remove_filter('post_limits', 'my_post_limit'); ?>
Step 6: You’re done!
Using the above code, you should now be able to use offsets and paging together.
Here is a downloadable file of all the code mentioned in this post.
Thank you John for asking such a great question.
Very cool, Ronald. This is something I’ve been meaning to figure out. I don’t use offset much myself but have a few theme users that do. I’m sure this will help out.
You just saved me loads of time.
An offset? What’s an offset?
Great write up Ronald. I’m using it on my site right now! Thanks!
I swear, Ronald comes up with the best tutorials.
Thanks y’all π
@Jeff: An offest means how many posts it should skip before displaying the rest of them. Setting offset equal to one means it skips your latest post and starts and the next one.
Thanks for sharing the mini tutorial, it’s big help especially for those who want to use offset and paging. π
Hi,
is there a link which we can see an example?
@Dresah,
I’m not sure what kind of example you’d want, since all it would be is a screenshot of a content block with the next/previous links.
You can kind of see it at my site raproject under the ‘Recent Articles’ heading, although I don’t use offsets.
@Ronald Huereca,
Thanks, this is enough for me π
I will try it, since I got confused to put page navigation on my site, I’ve used wp-page navi but seem not work well on my themes. Maybe you can give me a direction, then visit my site
Best regard
First of all, thanks for sharing the knowledge. I am trying to customize my WP so that index.php displays 1 post only and the archive pages display 5 posts per page. I tried the codes you provided both in this post and in the post on Paging and Custom WordPress Loops. Despite tricking the WP into using $wp_query in the loop like Aaron suggested, the maximum number of pages displayed is still controlled by the “posts per page” option set in Settings < Reading, which I set to 5. I currently have 10 posts. Therefore, on my index.php, the pagination navigation only goes to page 2, and returns a 404 error beyond page 2. Do you know how to tweak the codes so that on index.php, the page navigation will return all 10 pages (1 post per page), while on the archives pages it will return 2 pages (5 posts per page)? I suspect this involves tweaking the $max_num_pages variable used in the navigation functions in the links_template.php file. Right now the default sets the same $max_num_pages for all !is_single() files. I tried to set a conditional $max_num_pages for is_(home), so that the maximum number pages displayed will be equal to the total number of posts, not the value (total posts divided by posts per page) calculated by WP based on the posts per page option set in Settings. I haven’t been able to come up with the correct expression, if you have any ideas to share, it would be great for myself and many others. I’ve seen quite a few unresolved threads on this pagination issue in the WP Forums. Thanks again.
Hi, Sorry, there was a typo in my comment. Toward the bottom of my comment, I meant the conditional statement is_home(), not is_(home). Just wanted to clarify that. Thanks.
Dear Roanld, thanks A LOT for your excellent solution and tutorial. You had helped me with a problem that had annoyed my husband for a long time. T-H-A-N-K-S !!
I finally had reason to use this in a project. Thanks again for this tutorial.
Superb code!
However, showposts=5 doesn’t work if changed to a different value
To change the number of posts shown you have to set the $postperpage variable in the “my_post_limit” function to whatever number you want. For some reason the showposts doesn’t work.
Thanks for your reply John π
$postperpage=3 will work but when you remove the filter, how can you set $postperpage to wordpress default again?
Something to note: the $wp_query->max_num_pages variable will occasionally be incorrect when using this code. For example, if you have 7 posts, limited to 3 posts per page, with an offset of 1, max_num_pages will return 3 instead of 2, which means you will have a blank result for your third page. Here is a fix, which you can apply just before your pagination links:
$wp_query->max_num_pages = ceil(($wp_query->found_posts - $myOffset) / $postperpage);
This over-writes the max_num_pages variable after adjusting how many posts were found less your offset. The “ceil” function simply rounds the result up to the next highest integer after dividing the correct number of posts to display by the number of posts you have specified to display on a page.
Greg,
i’m dropping your code into the content_ nav function not sure this is correct because it’s breaking. If you could help that would be great.
function twentyeleven_content_nav( $nav_id ) {
global $wp_query;
$wp_query->max_num_pages = ceil(($wp_query->found_posts – $myOffset) / $postperpage);
if ( $wp_query->max_num_pages > 1 ) : ?>
<nav id="”>
<?php endif;
}
paging seems right after but the pagination disappears.
thank you so much for this great tutorial,
There just a little problem that i can not control in the showposts limit. i only can do it from control panel and not from here $wp_query->query(‘offset=’.$myOffset.’&showposts=5′.’&paged=’.$paged);
do u have any suggestion?
Unbelievable stuff, man. Worked like a charm. Thanks!
Basically, you are the most excellent person ever to have graced the face of this fair planet.
I have now been able to give the wall a rest, by not smashing my head against it anymore.
You have totally fixed my problem, saved my arse, and made my client very happy.
Thank you, thank you, thank you!
Toby π
Wow! A fix that just works like it should! Very nice!
This is great!! The only problem I have noticed is if the amount of posts equals the postperpage variable you still get the “Next” page link even though you have no additional posts. Any ideas? Thanks,
Josh
Is there any reason this is done in a separate loop than the main loop? will this work if i just try to do it with the main loop on the index.php page?
thank you so much for that, spent hours trying to fix it.
Hi,
You are AWESOME!!! I am having problem with offset and pagination to work at the same time and you save my day π
Thank you so much!
Offset and Paged together…this is Awesome !!!! Was looking for a solution for the conflict s that occured when i used them together and now your snippet had just saved my day…Thanks a lot π π