Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've a situation where I cannot get correct post count from category... and I've tried everything but customizing wp_list_categories with walker.

So I've category hierarchy:

cat1
 cat2 (total 8)
  cat3 (total 5)
  cat4 (total 3)

All posts are under cat2 and cat3-cat4. I'm displaying cat1 and want to show post count.

If I use following function:

function wp_get_postcount($id) {
  //return count of post in category child of ID 15
  $count = 0;
  $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;
}

I get total count of 16. Which is double the real amount, obviously counting twice.

Before this I tried:

$children_cats = get_categories(array(
        'hide_empty'    => 0,
        'taxonomy'      => 'category',
));

And used foreach on array and echoing out count. But it would return 0, obviously because parent cat has no posts selected under it...

wp_list_categories actually displays correct value. But I wasn't able to extend it with walked so I would get my complicated html:

<li>
                            <a class="subcatimg" href="<?php echo $cat_link; ?>"><?php if (function_exists('get_cat_icon_lite')) echo get_cat_icon_lite( $child->cat_ID );?><span><?php _e('Show All','medishop'); ?></span></a>
                            <h4><a href="<?php echo $cat_link; ?>"><?php echo $child->name; ?></a></h4>
                            <p><span><?php echo wp_get_postcount($child->cat_ID); ?></span> <?php _e('products in this category','medishop'); ?></p>
                        </li>

I'm really out of options. Any advice?

share|improve this question

5 Answers 5

I get total count of 16. Which is double the real amount, obviously counting twice.

The count property will return the number of posts in that specific category. You are getting 16 because those posts have both cat3 or cat4 and the parent category (cat2) assigned to them, and you're adding up the counts.

Assuming you are using that function like wp_get_postcount($id_of_cat2), just return the count property:

$term = get_term((int)$id, $taxonomy);

if(!($term instanceof WP_Error))
  return (int)$term->count;

// or show the error...
return 0;

(This is the same as $child->count in your code below)

But if you're trying to get the post count of all child categories of cat1, like wp_get_postcount($id_of_cat1), which according to that category hierarchy doesn't have any posts assigned to it, then add up the counts from the 2nd level. Your function seems to do exactly that.

share|improve this answer
    
This does not help me, I already know what is happening. But I cannot stop my code to double count which is the problem. –  Sandro Dzneladze Mar 17 '13 at 11:27
    
If you replace echo wp_get_postcount($child->cat_ID); with echo $child->count;, do you get the correct number? –  onetrickpony Mar 18 '13 at 11:07
    
As I said in OP, that was my first way of doing it. But it displays 0 as cat1 has no posts assigned to it. –  Sandro Dzneladze Mar 19 '13 at 6:43
    
If you don't want to assign posts to cat1 as well, use your function, and for the sub-categories you use the count property directly –  onetrickpony Mar 20 '13 at 1:23

Checking Daniel Llewellyn code and WordPress' WP_Query reference, I realized that we need to pass an array of array within the tax_query parameter. Otherwise, it'd just return all post counts.

Here is the little modified code:

if ( ! function_exists( 'ipt_kb_total_cat_post_count' ) ) :

/**
 * Simple function to get category post count including all subcategories
 *
 * @link http://wordpress.stackexchange.com/a/91551 Stackexchange
 * @param  int $cat_id Category ID
 * @return int         Total post count
 */
function ipt_kb_total_cat_post_count( $cat_id ) {
    $q = new WP_Query( array(
        'nopaging' => true,
        'tax_query' => array(
            array(
                'taxonomy' => 'category',
                'field' => 'id',
                'terms' => $cat_id,
                'include_children' => true,
            ),
        ),
        'fields' => 'ids',
    ) );
    return $q->post_count;
}

endif;

Hope it helps someone like me.

share|improve this answer

This isn't the perfect solution, but might work as a quick fix, depending on your needs.

Unfortunately, the way wordpress does this math, I don't think "child_of" is the way you want to go. However, you could just select cat1 as a category on the posts in question.

First, edit posts in Categories 3 & 4 and change from this:

cat1 []
  cat2 [x]
     cat3 [x]
     cat4 []

to this:

cat1 [x]
  cat2 [x]
     cat3 [x]
     cat4 []

Then fix your code to just count the # of posts in cat1, rather than all of its children.

I was having a related issue, and solved it this way. It's not recommended in every situation because it will break if the user doesn't select categories properly. However, used properly, and it will fix your count issue.

Additionally - if all posts are children of cat1 by default, to help the user in this instance, you could change the default category to 'cat1' for all new posts.

Settings > Writing.
share|improve this answer
    
I cannot move posts to cat1. –  Sandro Dzneladze Mar 19 '13 at 15:52
    
posts can have multiple categories. you mean your theme will break if posts are assigned to cat1? –  timshutes Mar 20 '13 at 2:46

try:

function wp_get_postcount($id) {
  //return count of post in category child of ID 15
  $q = new WP_Query(array(
    'nopaging' => true,
    'tax_query' => array(
      'taxonomy' => 'category',
      'field' => 'id',
      'terms' => $id,
      'include_children' => true,
  )));
  return $q->post_count;
}

caveat: I've not tested this.

share|improve this answer
1  
How would this code fix the OP's problem? Please add an explanation to your answer –  bungeshea_ Mar 20 '13 at 3:24
    
Also i would add 'fields' => 'ids' to make the query way way way faster. –  Bainternet Mar 20 '13 at 15:06

My understand is all the posts are assigned to third level category (i.e cat3 & and cat4) and to their immediate parent (i.e cat2). But the posts are not assigned to first level category (i.e cat1).

Now you want to count posts based on the top/first level category, if my understanding is correct, can you please tell me what is wrong with using the code below?

function wp_get_postcount($id) {
  //return count of post in category child of ID 15
  $count = 0;
  $taxonomy = 'category';
  $args = array('child_of' => $id);
  $tax_terms = get_terms($taxonomy,$args);
  foreach ($tax_terms as $tax_term) {
      if ($tax_term->parent == $id) {
            $count +=$tax_term->count;
      }
  }
  return $count;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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