These days, when performing searches, or even just looking at a list of pages, most people expect to see the total number of items in the list. If you’ve got a lot of content on your site, the standard WordPress search can return a lot of posts, and yet most themes don’t provide any feedback on the number of matched posts. While there are some plug-ins that provide that functionality, they are all unnecessary because WordPress provides that information in a simple variable.
The key is in the $wp_query object which holds everything you want to know about the query that produced the posts currently displayed on the screen. If you put a print_r($wp_query) somewhere, you’ll see the wealth of information available. The $wp_query->found_posts property returns the total number of posts which match the current query parameters.
Here’s a typical example of its use in search.php:
<h1>Search Results for '<?php echo wp_specialchars($s, 1); ?>' (<?php echo $wp_query->found_posts; ?> matches)</h1>
You can also use it in any of your other templetes:
<h1>Archive for <?php the_time('F, Y'); echo ' ('.$wp_query->found_posts; ?> matches)</h1>
<h1>Archive for <?php echo single_cat_title() . ' ('.$wp_query->found_posts; ?> matches)</h1>
Counting Pages
WordPress automatically seperates long lists of posts into pages holding at most the “Blog pages show at most” value set in Settings > Reading. Most templates provide navigation to move backward and forward through the pages using previous_posts_link() and next_posts_link(). What’s usually missing is any indication of just how many pages there are and where the user is up to. Fortunately this is easy to display as well.
The $wp_query object helpfully exposes the value of “Blog Pages Show At Most” as the posts_per_page property of the query_vars object. Using the php ceil function to roll up fractional values to the next highest integer, the total pages can be calculated as:
$totalpages = ceil($wp_query->found_posts / $wp_query->query_vars['posts_per_page']);
The current page being displayed is held by the global $paged variable which comes from the URL (all URL parameters are exposed in this way). The exception is the first page of any results list where $paged has no value (ie, its unset), which must be corrected for, ie: if (!isset($paged)) $paged = 1;
You now have everything you need to display a “Page x of n” type of message:
<?php
global $paged;
if (!isset($paged)) $paged = 1;
$totalpages = ceil($wp_query->found_posts / $wp_query->query_vars['posts_per_page']);
echo 'Page ' . $paged . ' of ' . $totalpages;
?>
This can also be easily integrated into the page navigation:
<div class="navigation">
<span class="alignleft"><?php previous_posts_link('« Newer'); ?></span>
<span class="alignright"><?php next_posts_link('Older »'); ?></span>
<?php echo 'Page '.$paged.' of '.$totalpages; ?>
</div>
In this example, the styling for the navigation class has text-align:center to position the Page x of n display in the center with the previous and next controls floated to the left and right.
Using $paged and $totalpages also gives you the foundation to implement a direct page navigation system, using either clickable page numbers or a drop-down list of pages.

