Customizing Post Counts in WordPress

June 20, 2012

I often find when developing WordPress themes or custom post types, I want to customize my post counts to a level that isn’t readily available to the average user. WordPress let’s you set the number of posts to show for on each page through the admin options, but this isn’t always desirable.

Say you have a blog on your site and on that blog you want 10 posts to show at a time. Done, simple as pie. Well say you blog about several different things and some of your categories you wish you could have 15 or 20 posts per page. On top of that let’s say your blog is a food blog and you have a custom post type for recipes specifically. On that post type you would like to list 5 recipes a page. This gets a little bit trickier.

At first I would just customize the different template files to modify the posts_per_page query variable. This seemed to work fine for me but at times, I would get strange 404 errors that shouldn’t be arise, or so I thought. In those cases I would often just switch to running a secondary query and abandon the archive model altogether. But as I thought about it, I decided that wasn’t the way I should or would like to do that. In closer examination I realized that the 404 pages were not in fact rogue, they were actually supposed to be there.

To explain this, let’s step back to the example above. So our blog is set to 10 posts per page for blog entries and 5 for recipes. For arguments sake I have 18 recipes in the database and I have customized the the archive template for recipes to pull 30 recipes. On the third page, I would receive a 404 error, but I shouldn’t get one, because 8 posts still need to be shown. (page 1 -> 5; page 2 -> 5; page 3 -> 5; page 4 -> 3 = 18)

When I thought about it, it made perfect sense WordPress is really setting the marker at 10 posts per page, then I am modifying it. So page one actually gets to post 10 page two gets all the way to post 18, even though it hasn’t shown it. What we actually need to do is modify the posts_per_page variable pre getting the posts.

Luckily WordPress has delivered once again a simple way to do that. All you have to do is add a filter to the pre_get_posts hook. This hook is super useful for manipulating the query, but careful, with great power comes great responsibility.

//add our filter
add_action('pre_get_posts', 'customize_post_counts');
function customize_post_counts($query){
/* we don't want to modify the admin post queries 
  or anything other special queries you may have written.
  So we can check and see if it is the main query 
  and not in the admin area.
   if(!is_admin() && $query->is_main_query()){
	  $query->set( 'posts_per_page', 15 ); 
          // set posts per page on category pages
	  $query->set( 'posts_per_page', 5 ); 
          // set posts per page on recipe pages

If it passes through that if statement above without setting that query variable, it will default to you WordPress defined admin option. The codex on that filter provides some other good examples and pointers.

Again, this code is just an example so don’t use it directly on your production site, but feel free to modify it and make it work for you. Also the pre get posts filter can be used to accomplish other things, such excludes specific post categories, formats or authors. For more information on The WP_Query class check out the codex page. Seriously, anything you want is probably possible through that.

Comments are closed.

« Back to Blog