Count posts that have specific taxonomy term attached

When upgrading our portfolio I’m looking for something that shows the number of posts in a (current) category of a post type.

Example: I have a category with ‘features’. Each feature has it’s own description, apps related and blog related posts page

I’m fetching the current category with:

<?php $cat_id = get_query_var('cat'); ?>

and get posts with:

 <?php query_posts("post_type=apps&cat=$cat_id&showposts=3");?>

How is it possible to count the posts of post_type=apps and category=$cat_id ?

I’m sorry for my lack of PHP/WP experience.. does anyone know how to get these 2 things working?

Thanks in advance.

4 Answers
4

Public API for the rescue

category is a Taxonomy that’s already built in. Therefore it’s quite easy to get its term count with get_terms( $tax, array( /* args */ ) );

$terms = get_terms( 'category', array(
    'fields' => 'count',
) );

This will do a pretty fast COUNT (*) query so you don’t have to worry about performance.

Alternate solution

You could as well just do a normal call to get_terms() and then alter the selects with the filter:

// The core filter:
apply_filters( 'get_terms_fields', $selects, $args )

// Example callback:
add_action( 'get_terms_fields', 'wpse105174_get_terms_fields_cb', 10, 2 );
function wpse105174_get_terms_fields_cb( $selects, $args )
{
    return array( 't.term_id', 'COUNT(*)' );
}

…where $selects is aan array (which will be imploded to a comma separated string).

Making it even faster

You could then further modify the query and restrict it to only some specific categories (terms/taxons) with a WHERE t.slug = whatever

// The core filter:
apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args );

// Example callback:
add_action( 'terms_clauses', 'wpse105174_terms_clauses_cb', 10, 3 );
function wpse105174_terms_clauses_cb( $pieces, $taxonomies, $args )
{
    $pieces['where'] = " WHERE t.slug = whatever";
    // Or do some `str_replace`, `preg_replace`, whatever fits in here

    return $pieces;
}

You could set the $pieces['join'] = ''; as well if you don’t need access to the term_taxonomy-table.

Cache it

Finally you could utilize the Transients API to save your results (as serialized array) to the DB, so you don’t have to query the count every time you need it.

Leave a Comment