I am using WordPress and on the search page I need to grab the number of posts within the category and display it next to the name. Like so
Cat 1 (3) Cat 2 (1) Cat 3 (18) ....
Currently I am using the get_categories()
functions which gives you an object and grabbing the count with $cat->count()
. This grabs the total number of posts within the term but I need to grab that count only from the post within the current query. I am using pre_get_posts
to update the query. Anybody know of a way to do this?
Here is my current code block
foreach ( get_categories() as $cat ) {
if ( $cat->parent === 0 ) {
$checked = ( in_array( $cat->slug, $check ) ) ? 'checked' : '';
printf( '<input id="%1$s" %4$s type="checkbox" name="category[%1$s]"><label for="%1$s" >%2$s ( %3$d )</label><br>',
$cat->slug,
$cat->name,
$cat->count,
$checked
);
}
}
Here is my pre_get_posts
action:
add_action( 'pre_get_posts', 'breed_search_query' );
function breed_search_query( $query ) {
$cats = ( isset( $_GET['category'] ) ) ? implode( ',', array_keys( $_GET['category'] ) ) : null;
$search = ( isset( $_GET['s'] ) ) ? sanitize_text_field( $_GET['s'] ) : null;
if ( ! is_admin() && $query->is_main_query() && is_search() ) {
$query->set( 'post_type', 'post' );
$query->set( 'posts_per_page', 8 );
$query->set( 's', $search );
$query->set( 'category_name', $cats );
}
}
Nice and interesting question must say. Unfortunately, you are not going to get this to work with get_categories
, so you will need another approach here.
Here is how we will do it:
Create a very lean custom query to get all the post ID's from all posts matching the query
Get all the categories attached to a post
Loop through all the posts and the categories within the posts and build an array with the category names as keys and post ID's as values
Loop through this new array, and display the category name and also count and display the amount of posts for that specific key ( category )
(NOTE: The following code is untested and needs at leat PHP 5.4+ due to the new array syntax ([]
))
$cats = ( isset( $_GET['category'] ) ) ? implode( ',', array_keys( $_GET['category'] ) ) : null;
$search = ( isset( $_GET['s'] ) ) ? sanitize_text_field( $_GET['s'] ) : null;
$args = [
'post_type' => 'post',
'nopaging' => true, // Gets all posts
's' => $search,
'category_name' => $cats,
'fields' => 'ids', // Makes the query extremely lean, excellent for performance, only get post ID's
];
$q = get_posts( $args );
// Define our $category_array which will hold the category name/post ID's array
$category_array = [];
// Define our $category_info array which will hold the category name as key and the object as value
$category_info = [];
foreach ( $q as $post ) {
// Get the categories attached to a post
$categories = get_the_category( $post );
foreach ( $categories as $category ) {
// Create our array which will hold the category name as key and post ID's as values
$category_array[$category->name][] = $post;
// Create an array to hold the category objects. Use names as keys and objects as values
$category_info[$category->name] = $category;
} // endforeach $categories
} // endforeach $wp_query->posts
wp_reset_postdata();
// Sort the array keys alphabetical. You can change or remove this as necessary
ksort( $category_array );
foreach ( $category_array as $k=>$v ) {
$category_slug = $category_info[$k]->slug;
$category_parent = $category_info[$k]->parent;
$checked = ( in_array( $category_slug, $check ) ) ? 'checked' : ''; // Just make sure that $check is defined somewhere
// Build our string
printf ( '<input id="%1$s" %4$s type="checkbox" name="category[%1$s]"><label for="%1$s" >%2$s ( %3$d )</label><br>', // I have not modified anything in this line
$category_slug, // Holds the category slug
$k, // Holds the category name
count( $v ), // Counts and return the post count
$checked
);
} // endforeach $category_array
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With