6/19/2008 ↓

How to: Offsets and Paging

If you like this post, please subscribe to our RSS feed to read our new posts every day.

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('&laquo; Previous') ?></div>
  <div class="alignright"><?php next_posts_link('More &raquo;') ?></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.

1 Star2 Stars3 Stars4 Stars5 Stars (5 votes, average: 4.8 out of 5)
Loading ... Loading ...

Friends

Translate

Translate to German Translate to Spanish Translate to French Translate to Italian Translate to Portuguese Translate to Japanese Translate to Korean Translate to Russian Translate to Chinese

Latest Videos

19 Comments | Leave a comment | Comments RSS

  1. 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.

    [Reply]

    Justin Tadlock (26 comments.) — 06/19/2008 @ 6:33 pm
  2. An offset? What’s an offset?

    [Reply]

    Jeff — 06/19/2008 @ 6:35 pm
  3. Great write up Ronald. I’m using it on my site right now! Thanks!

    [Reply]

    John Kolbert (23 comments.) — 06/19/2008 @ 7:10 pm
  4. I swear, Ronald comes up with the best tutorials.

    [Reply]

    Ian Stewart (17 comments.) — 06/19/2008 @ 8:07 pm
  5. Thanks y’all :)

    [Reply]

    Ronald Huereca (66 comments.) — 06/19/2008 @ 8:30 pm
  6. @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.

    [Reply]

    John Kolbert (23 comments.) — 06/19/2008 @ 8:31 pm
  7. Thanks for sharing the mini tutorial, it’s big help especially for those who want to use offset and paging. :)

    [Reply]

    Martin Welch (5 comments.) — 06/19/2008 @ 9:12 pm
  8. Hi,
    is there a link which we can see an example?

    [Reply]

    Dresah (2 comments.) — 06/20/2008 @ 3:03 am
  9. [...] Offsets and Paging [...]

    WordPress Weekly Episode 21 | Jeffro2pt0 — 06/20/2008 @ 6:25 am
  10. @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.

    [Reply]

    Ronald Huereca (66 comments.) — 06/20/2008 @ 9:49 am
  11. @Ronald Huereca,

    Thanks, this is enough for me :)

    [Reply]

    Dresah (2 comments.) — 06/20/2008 @ 2:04 pm
  12. 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

    [Reply]

    Roni (9 comments.) — 06/22/2008 @ 11:40 pm
  13. 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.

    [Reply]

    Morsels of Memory (2 comments.) — 06/24/2008 @ 12:02 am
  14. 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.

    [Reply]

    Morsels of Memory (2 comments.) — 06/24/2008 @ 5:53 am
  15. 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 !!

    [Reply]

    celita — 08/15/2008 @ 12:24 am
  16. I finally had reason to use this in a project. Thanks again for this tutorial.

    [Reply]

    Ian Stewart (17 comments.) — 08/31/2008 @ 9:52 am
  17. Superb code!

    However, showposts=5 doesn’t work if changed to a different value

    [Reply]

    Jose — 11/25/2008 @ 5:01 pm
  18. 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.

    [Reply]

    John Kolbert (23 comments.) — 11/28/2008 @ 12:30 am
  19. Thanks for your reply John :)

    $postperpage=3 will work but when you remove the filter, how can you set $postperpage to wordpress default again?

    [Reply]

    Jose — 11/28/2008 @ 9:22 am

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(required)

(required, will not be published)


S2