So I have a normal search on one of my Wordpress sites.
I know how to get the total amount of posts with: $wp_query->found_posts
but I was wondering how to get a total count for each post type?
For example:
14 Total Results
10 Post Results
4 Page Results
Edit
Found a solution for now, but would love to know if there is a way to do this without running 2 queries. Basically I am doing this before my normal search results loop.
<?php
$args = array(
's' => $_GET['s'],
'posts_per_page' => -1
);
$my_query = new WP_Query( $args );
$types = array();
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post();
$types[$post->post_type]++;
endwhile;
}
?>
So I have a normal search on one of my Wordpress sites.
I know how to get the total amount of posts with: $wp_query->found_posts
but I was wondering how to get a total count for each post type?
For example:
14 Total Results
10 Post Results
4 Page Results
Edit
Found a solution for now, but would love to know if there is a way to do this without running 2 queries. Basically I am doing this before my normal search results loop.
<?php
$args = array(
's' => $_GET['s'],
'posts_per_page' => -1
);
$my_query = new WP_Query( $args );
$types = array();
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post();
$types[$post->post_type]++;
endwhile;
}
?>
Share
Improve this question
edited Jul 17, 2016 at 14:13
Corey
asked Jul 17, 2016 at 13:55
CoreyCorey
3217 silver badges17 bronze badges
1 Answer
Reset to default 1You're essentially running the same query twice, instead of looping over a second query, why don't you loop over $wp_query
?
$types = array();
if( have_posts() ) {
while (have_posts()) {
the_post();
if ( empty( $types[$post->post_type] ) {
$types[$post->post_type] = 0;
}
$types[$post->post_type]++;
}
wp_reset_postdata();
rewind_posts();
}
You'll notice I added 3 things:
- The code in your question generates notices and warnings,
$type
is an empty array and when you first attempt ot increment a post type count, there is no existing value ( afterall the array is empty right? There's nothing to increment ) - Whenever you call
the_post
on a custom query you need to callwp_reset_postdata
, I've added it here since we'll be rewinding the main query back to the start, but this should always go inside the if statement, you don't want to cleanup if you've not done anything to clean up. Some people will usewp_reset_query
. That function is for cleaning up after a call toquery_posts
. Never usequery_posts, and by conjunction you should never need to use
wp_reset_query` an if statement - I added a call to
rewind_posts
, this rewinds the main loop back to the beginning so that you can loop over it a second time. note that I put it inside the if statement, I'm only rewinding if there is something to rewind
Alternatively, loop over $wp_query->posts
. Note that it's more elegant to use the loop, and that this may not be a simple array, looping over it may have performance consequences due to the way WP_Post
objects work
global $wp_query;
$types = array();
if( !empty( $wp_query->posts ) ) {
foreach ($wp_query->posts as $p ) {
if ( empty( $types[$p->post_type] ) {
$types[$p->post_type] = 0;
}
$types[$p->post_type]++;
}
}
There are some obvious refactors you can do from here, e.g. creating a function that takes a WP_Query
object and returns an array of counts, letting you do this for any query not just the main one, and making your code easier to read