Monday we displayed post counts. Well, what about taxonomies? That’s a little more complicated, I’m afraid.
Posts are easy. You pick a post type, you display the number of published posts, you walk away. Taxonomies though are a mixed bag. By default you have categories (category) and tags (post_tag) and inside them, you have terms. For example ‘Uncategorized’ is a category. The problem is that to check if a taxonomy exists (and display a post count), you have two have both the taxonomy name and the term name.
While you think you could just write a loop ‘If the term name isn’t in categories, it’s in tags!’ the reality is that anyone can add any taxonomy and, worse, term names aren’t unique. It’s ironic here, because I desperately wanted term names and slugs to not be unique. I wanted to have a tag for ‘random’ and a category for ‘random’ and they all have the same slug names. So here I am now, realizing I’ve set myself up for disaster.
The options are simple:
- Force people to use term and taxonomy
- Somehow be clever
I went with option 2. Allow people to use term and taxonomy, but if they don’t, find the first instance and go for it.
The Code
// [numtax term="term_slug" taxonomy="tax_slug"]
function numtax_shortcode( $atts ) {
$attr = shortcode_atts( array(
'term' => '',
'taxonomy' => '',
), $atts );
// Early Bailout
if ( is_null($attr['term']) ) return "n/a";
$the_term = sanitize_text_field( $attr['term'] );
$all_taxonomies = ( empty( $attr['taxonomy'] ) )? get_taxonomies() : array( sanitize_text_field( $attr['taxonomy'] ) );
//$all_taxonomies = get_taxonomies();
foreach ( $all_taxonomies as $taxonomy ) {
$does_term_exist = term_exists( $the_term, $taxonomy );
if ( $does_term_exist !== 0 && $does_term_exist !== null ) {
$the_taxonomy = $taxonomy;
break;
} else {
$the_taxonomy = false;
}
}
// If no taxonomy, bail
if ( $the_taxonomy == false ) return "n/a";
$to_count = get_term_by( 'slug', $the_term, $the_taxonomy );
return $to_count->count;
}
add_shortcode( 'numtax', 'numtax_shortcode' );
There are two moments where I bail out early. If they forgot to put in a term, display “N/A”. The same if we get all the way to the end and there was no found taxonomy.
Also if someone puts in a taxonomy, I treat it as an array in order to be lazy and not repeat myself. Good coding doesn’t repeat, so since I have to loop the array of found taxonomies in order to find the matchup, I may as well use it once to find the same data when I know what I have.
I admit, I was really excited here since I finally got to use ternary operations. I’ve known how they work for ages, but I never had a moment where it was so obvious to use them.

