Get category count relative to the current query

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)
….

Read More

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 );
    }
}

Related posts

1 comment

  1. 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 )

    THE CODE:

    (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
    

Comments are closed.