DiggingIntoWordPress

by Chris Coyier & Jeff Starr

Two Ways to Limit the Number of Posts without a Plugin

Posted by on

Let’s say your blog is set to display ten posts per page, as specified via the WordPress Admin under Settings > Reading. Once set, ten posts will appear on your home page, archive pages, search results, and so on. In other words, if it isn’t a single-view page or an actual “page” page, you’re gonna get ten posts per page. It’s a global setting.

But what if you want to display different numbers of posts for different types of page views? For example, instead of showing just ten posts on your search-results pages, you may want to show a whole bunch, like maybe fifty or something. Perhaps you would also like to limit the number of posts displayed on your category archives to only five. Of course, many of us know the easy way to do this: install Custom Query String Reloaded (404 link removed 2013/12/29) or Custom Post Limits, tweak a few settings, and call it good. But.. this does require commitment to yet another plugin, which is a good reason for doing things the “hard” way..

Method 1

Fortunately, we can account for the latter scenario without relying on a plugin. Normally, the loop controls the number of posts displayed via the while(have_posts()) condition, as shown in this extremely boring example of a typical loop:

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

	<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
	<p>?php the_time(); ?></p>
	<?php the_content(); ?>
	<p><?php the_tags(); ?></p>

<?php endwhile;?>

	<p><?php next_posts_link(); ?></p>
	<p><?php previous_posts_link(); ?></p>

<?php else : ?>

	<h1>Not Found</h1>
	<p>Silly monkey.</p>

<?php endif; ?>

What’s happening here is that we are running the loop only if we have posts, and only while the number of posts is less than or equal to the amount specified in the Admin area. Thus, limiting the number of posts is simply a matter of replacing “while(have_posts())” with something more restrictive.

There are probably a zillion ways of doing this, but the easiest that I have found is to simply setup a counter variable to keep track of each iteration of the loop. Once the counter variable reaches the specified value, the loop stops. Here’s the previous example loop showing the required modifications:

<?php $i = 1; while (have_posts() && $i < 6) : the_post(); ?>

	<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
	<p>?php the_time(); ?></p>
	<?php the_content(); ?>
	<p><?php the_tags(); ?></p>

<?php $i++; endwhile; ?>

	<p><?php next_posts_link(); ?></p>
	<p><?php previous_posts_link(); ?></p>

<?php else : ?>

	<h1>Not Found</h1>
	<p>Silly monkey.</p>

<?php endif; ?>

Notice that in the first line we are initiating the counter variable “$i” and then setting its limit at “6”. We also add “$i++;” before the “endwhile” statement to increase the count by one for each iteration of the loop. The result of these modifications is that the loop will now run only five times (as specified in the first line) instead of ten times (as specified in the WordPress Admin).

Just keep in mind that this trick only works when you want to limit the total number of posts displayed on a particular page. Even so, it is still possible to avoid a plugin by setting your default post display to something high, like 20 or 30. Then, your blog displays the highest number of posts where you want them, and everything less is customized by limiting this default number with a couple lines of code. This technique could also be useful for designing themes that required a specific number of posts displayed in certain areas of the blog.

Method 2

Or, you could just use query_posts to create a custom query and specify the showposts parameter with a value of “5” (or whatever number you wish). Here is what our original loop example looks like using the query_posts function:

<?php query_posts('showposts=5'); if (have_posts()) : while (have_posts()) : the_post(); ?>

	<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
	<p>?php the_time(); ?></p>
	<?php the_content(); ?>
	<p><?php the_tags(); ?></p>

<?php endwhile;?>

	<p><?php next_posts_link(); ?></p>
	<p><?php previous_posts_link(); ?></p>

<?php else : ?>

	<h1>Not Found</h1>
	<p>Silly monkey.</p>

<?php endif; wp_reset_query(); ?>

Notice the two additions to the original loop: in the first line, we added the query_posts function with the required posts_per_page parameter set to 5. Then, in the last line, we invoke the mystical powers of wp_reset_query to reset the original posts query. Resetting the query ensures that it’s available elsewhere in the template and is just good practice in general when using query_posts.

The pros of using query_posts to modify the number of posts is that you can go either way — you can either decrease or increase the total number of posts displayed on any page — no plugins necessary.

The cons of using the query_posts method mainly involve the disruption of the original wp_query object normally used to communicate parameters involving page, category, search, and other properties to the SQL query*. Avoiding this drama is one of the reasons why using a simple counter variable (as described in the first half of the post) is often the preferred method (multiple loops, anyone?).

*Note: It is possible to include this default information in the query_posts query, but doing so is a bit beyond the scope of this article.

19 Responses

  1. Great tip. But do these take into account paging? I’ve had problems in the past when limiting the number of posts where the paging does not work correctly.

    • Joshua, in my e,experience using the second method shouldn’t break pagination as it’s a built in WordPress function. Using a counter could break pagination code.

    • Jeff Starr

      Todd is correct – paging should work fine using the query_posts method.

  2. Great tip, Jeff! The rule of thumb that I follow is:

    1) Use query_posts() for your main content loop.
    2) For any secondary loops (i.e. most popular posts), create a new query with the WP_Query object.

    Codex article on WP_Query object

  3. Thanks Jeff – I didn’t know about wp_reset_query – now I know I was having trouble using more then one query_posts

  4. hi good post but, if i want to show all my previous published posts in the category or tage page what is the needed code .
    i only show post titles in these pages and i use ( Custom Query String ) to show all post .
    Is there are any manual way to show all posts in archive page

  5. Sonya Lynn December 21, 2009

    Was excited to give this a try…

    the first method didn’t work for me at all. Broke my site, returned a blank white page…

    the second method, I applied to a custom category-5.php, and worked, but showed posts that aren’t in that particular category. (shows all posts)

    meh.

    • Jeff Starr

      Yeh, the first method is for specific cases and isn’t always going to gel. But the second method is sound and used successfully on many sites. Remember that query_posts is using a custom query and so any default query parameters (such as the category) will need to be respecified like so:

      &cat=n

      ..where “n” is the number of your category.

      I hinted at this situation in the last couple of paragraphs, but perhaps more is needed..

  6. wow, thats great… ;)

    thanks man, it comes in handy…

  7. I’ve come across a problem using query_posts recently where if the posts_per_page is set to less then the Max posts per page set in the admin area the “older entries” and “newer entries” links return a 404 error. It seems to break pagination.

  8. I am sorry to say that this post is a good reason to NOT buy the book. The first method results in a blank page. The second method breaks the pagination, exactly like Pavel wrote. Both methods are useless. A waste of time.

    • Jeff Starr

      Wow, you’re basing your decision on a single post? We share tons of great content with the community, both here at digwp.com and at our personal sites. Obviously not everything we post is going to be useful to everybody, but it doesn’t stop us from trying to help.

  9. not ‘posts_per_page’ but ‘showposts’ in the explanation of Method 2 ;-)

    And for what it’s worth, Id use WP_Query and never query_posts().

    http://codex.wordpress.org/Function_Reference/WP_Query

  10. Nice post, it is similar to others I have seen, however with the Method 1, I have tried, it does limit the number of posts shown, however, when using the next page, the difference in posts shown are now missing. For example, 10 posts, limit to 5 posts. Page 1 will show posts 1 through 10. Page 2 will show posts 11 through 20. When limiting the number to 5, Page 1 will show 1 through 5, Page 2 will show 11 through 15. Any thoughts?

    I just tested Method 2, with the same results.

    Unless I am overlooking something …. the posts are limited, but something else is missing.

  11. Perfect! Exactly what I was looking for. I searched elsewhere and found people going extremely in depth into The Loop, and setting up all kinds of queries + variables… I really love the i++ counter technique. Thanks man :)

  12. Thanks – this was helpful. For some reason, my theme is overriding the Setting > Reading values, so I had to do this manually. I used option 1 for the record and it works just fine.

    Thanks,
    Steinar

Comments are closed. Contact us with any critical information. Thank you!

Code is poetry