I have found this code somewhere, it counts posts but only which are under specific category. I would appreciate if someone could expand this so it would count all posts which also belong to its child categories?

function wp_get_cat_postcount($id) {

      $cat =  get_category_by_slug( $id ); 
      $count = (int)$cat->count;
      $taxonomy = 'category';
      $args = array(
        'child_of' => $id,
      $tax_terms = get_terms($taxonomy,$args);
      foreach ($tax_terms as $tax_term) {
        $count +=$tax_term->count;
      return $count;

1 Answer 1


The function you are using are scrambled and does not make much sense. Also, it is very static in that you cannot return a count according to custom parameters like post type, post status, or custom field. Another thing to note, if a post belongs to a term and one of its child terms, the post will be counted twice, so you will end up with a post count which is more than what you actually have.

IMHO, I will just make use of a custom query to make the function dynamic and to return a true count instead of a bloated one due to posts belonging to a parent and a child term.


The tax_query has a parameter called include_children, which by default is set to true. This parameter will include all child terms of the terms passed to the terms parameter, so it will return posts from the passed terms and all of it's children.

Secondly, we only need to query one post to get a post count. What WP_Query does by default is, it will continue to search the db for matching posts, even though it has already found the required posts matching the query. This is done in order to calculate pagination, and a count of all these posts matching the query is stored in the $found_posts property of the query object.

To save on db calls and time spend doing it, we will also just query the ID post field and not the complete WP_Post object.


First of all, a few notes

  • The code is untested and might be buggy. Be sure to test this first on a local test install with debug turned on

  • The code requires a minimum of PHP 5.4

I will comment the code as I go along so you can follow and understand what will be happening

 * Function to get post count from given term or terms and its/their children
 * @param (string) $taxonomy
 * @param (int|array|string) $term Single integer value, or array of integers or "all"
 * @param (array) $args Array of arguments to pass to WP_Query
 * @return $q->found_posts
function get_term_post_count( $taxonomy = 'category', $term = '', $args = [] )
    // Lets first validate and sanitize our parameters, on failure, just return false
    if ( !$term )
        return false;

    if ( $term !== 'all' ) {
        if ( !is_array( $term ) ) {
            $term = filter_var(       $term, FILTER_VALIDATE_INT );
        } else {
            $term = filter_var_array( $term, FILTER_VALIDATE_INT );

    if ( $taxonomy !== 'category' ) {
        $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy ) )
            return false;

    if ( $args ) {
        if ( !is_array ) 
            return false;

    // Now that we have come this far, lets continue and wrap it up
    // Set our default args
    $defaults = [
        'posts_per_page' => 1,
        'fields'         => 'ids'

    if ( $term !== 'all' ) {
        $defaults['tax_query'] = [
                'taxonomy' => $taxonomy,
                'terms'    => $term
    $combined_args = wp_parse_args( $args, $defaults );
    $q = new WP_Query( $combined_args );

    // Return the post count
    return $q->found_posts;


You can use the function in the following ways


Single term (term ID 21) with default category taxonomy

$count = get_term_post_count( 'category', 21 );
echo $count;


Array of term ids with custom taxonomy my_taxonomy

$count = get_term_post_count( 'my_taxonomy', [21, 41, 52] );
echo $count;


Single term from default category taxonomy from custom post type cpt and post status trash

$args = [
    'post_type'   => 'cpt',
    'post_status' => 'trash'
$count = get_term_post_count( 'category', 21, $args );
echo $count;


If you need to get a post count from all terms of a given taxonomy, simply set the $term parameter to all

$count = get_term_post_count( 'category', 'all' );
echo $count;
  • Ty for your trouble, but the code get_term_post_count( 'category', 21 ) always gives me a maximum number, it probably counts every post, neverthless which ID of a category I pass as parameter.
    – Marko
    Nov 8, 2015 at 9:54
  • 1
    I'll be home in about 30min time, then I will quickly test the code. Looks like a bug somewhere. Will get back to you Nov 8, 2015 at 9:57
  • Oups, there is a typo which wasnt triggered by debug. (defaults -> default). Thank you very much
    – Marko
    Nov 8, 2015 at 10:02
  • Thanks for the reply, I will fix the typo. Glad the code otherwise worked. Enjoy ;-) Nov 8, 2015 at 10:09
  • Isn't there a need to include wp_reset_postdata() at the end of the function?
    – Yuri
    Mar 30 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.