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.