WordPress treats every page/post-listing just about the same. Whether it’s the homepage, a blog category, search results, or even your average page, the same basic logic is used to generate it. This also means that the same settings, including the number of posts displayed per page, are used across the board. However, this is not always desirable.

The Goal

The basic goal of a site search is to find information quickly; however, it is becoming more and more commonplace to see increasingly stylized post listings. In my eyes, this runs the risk of becoming counter-intuitive to this goal. Because of this, it is my personal preference to simplify my search results and to show more results. Because searches rely on the same setting (found in Settings » Reading » Blog pages show at most) as any other WordPress page when determining the number of listings to show, we have to get a little creative in order to show a different amount.

How Not to Do It

Most blog posts or WordPress.org forum posts will recommend using the query_posts() function in order to alter the number of search listings shown. They advise inserting something similar before the loop in your themes search.php.

However, this neglects one important fact. WordPress already runs the query once before it even gets to this query_posts() call. This means that you are essentially doubling the number of database calls WordPress needs to do in order to retrieve the correct number of posts. If an efficient, quickly-loading site is important to you (I know it is to me), this should be a concern. This is even more important with the recent news that Google is now incorporating page-load time into its pagerank algorithm.

A Better Solution

The obvious solution is to alter the original query before it is executed. This is made fairly simple with WordPress filters (noticing a common theme in our WordPress-related posts?). Using the pre_get_posts filter, we can change the query parameters before it is translated into an actual MySQL query. Simply insert the following code into the functions.php file of your theme. It’s so simple, I hope this technique will become more commonplace.

function change_wp_search_size($query) {
	if ( $query->is_search ) // Make sure it is a search page
		$query->query_vars['posts_per_page'] = 10; // Change 10 to the number of posts you would like to show

	return $query; // Return our modified query variables
add_filter('pre_get_posts', 'change_wp_search_size'); // Hook our custom function onto the request filter

Any function that is hooked into the pre_get_posts filter will automatically be passed an WP_Query Object containing any parameters that intends to use to generate the database query. All we have to do is change the posts_per_page parameter to the number of results we would like to show.

We must first determine if we are even on the search results page. This is as easy as testing to see if $query->is_search is set. Then, it’s simply a matter of returning our modified query paramaters to WordPress and letting WordPress do it’s magic.

A few additional notes

If you don’t want to limit the number of posts shown at all, simply set $query->query_varts['posts_per_page'] to -1. Also, this technique is not limited to the search page only. You can also test for $query->is_cateogry, $query->is_tag, $query->is_archive, $query->is_date, and etc. And if you want to test for a specific category you can use a conditional statement similar to the following:

if ($query->query_vars['cateogry_name'] == 'category_slug')

The Wrap-up

Though this solution may contain a few more lines of code than a query_posts() solution, it is still superior for two reasons.

  1. It is quicker by nearly halving the number of database calls
  2. We separate logic and presentation as much as possible, which should be a ever-present goal in web programming and design

Thanks to soulsizzle for the information.