Custom Taxonomy Friendly Archives
While not all themes utilize custom taxonomies as part of the theme itself (perhaps for portfolios), it is absolutely vital that all themes include complete support for custom taxonomy archives. What I see far too often are themes that do not adequately support custom taxonomies in their archive templates and end up causing a PHP error to occur when viewing a taxonomy archive. This quick tutorial is going to show you a really easy way to avoid this problem and provide complete support for custom taxonomies, all in a single template file.
This tutorial is going to assume that all category, tag, and taxonomy archives are displayed with your single archive.php file, as opposed to separate files for category.php, tag.php, etc.
Most of the time, at the top of the archive.php file, theme developers will place something like this:
<h2><?php echo single_cat_title(); ?></h2>
<div class="category-description"><?php echo category_description(); ?></div>
Or this:
<h2><?php echo single_tag_title(); ?></h2>
<div class="tag-description"><?php echo tag_description(); ?></div>
Or a combination:
<?php if( is_category() ) { ?>
<h2><?php echo single_cat_title(); ?></h2>
<div class="category-description"><?php echo category_description(); ?></div>
<?php } elseif( is_tag() ) { ?>
<h2><?php echo single_tag_title(); ?></h2>
<div class="tag-description"><?php echo tag_description(); ?></div>
<?php } ?>
These are all perfectly fine functions to use, except that they do not work with custom taxonomies and will actually result in an error being thrown (if not using an is_category/is_tag conditional).
If we look at the source code for the tag_description() function, we will see that it is actually just a reference to the similar term_description() function, but with the “post-tag” parameter set as default.
/**
* Retrieve tag description.
*
* @since 2.8
*
* @param int $tag Optional. Tag ID. Will use global tag ID by default.
* @return string Tag description, available.
*/
function tag_description( $tag = 0 ) {
return term_description( $tag );
}
The term_description() function is really nice because (if we look at the source), we see that it will actually detect the current taxonomy type that is being displayed and display the description for the term from the proper taxonomy, instead of throwing the error like tag_description() does. See the function below:
/**
* Retrieve term description.
*
* @since 2.8
*
* @param int $term Optional. Term ID. Will use global term ID by default.
* @param string $taxonomy Optional taxonomy name. Defaults to 'post_tag'.
* @return string Term description, available.
*/
function term_description( $term = 0, $taxonomy = 'post_tag' ) {
if ( !$term && ( is_tax() || is_tag() || is_category() ) ) {
$term = get_queried_object();
$taxonomy = $term->taxonomy;
$term = $term->term_id;
}
$description = get_term_field( 'description', $term, $taxonomy );
return is_wp_error( $description ) ? '' : $description;
}
There is also a great function for the taxonomy term title that functions the same way: single_term_title()
This all means that we can simply use the following in our archive.php and it will work for all taxonomies:
<h2><?php echo single_term_title(); ?></h2>
<div class="tax-description"><?php echo term_description(); ?></div>
That is much better than creating multiple files to deal with the different taxonomies (unless you’re creating custom layouts for each) and is also much safer.
Thanks for sharing Pippin!
Gladly 🙂
Have to give this a spin. Thanks Pippin.
This is great Pippin! So simple. I work with WordPress every single day but I never find this stuff until someone points it out. I suppose some snowy weekend I should look through the core files in detail!
Brilliant as usual Pippin!
I’ve work with cpt enough that I should have known this.
And what Randy says is true! I learn way more from the great wp community than any other open source project out there.
Thank you SO MUCH 😀
I was trying to do that since a long time !
Hi Pippin,
Just to let you know, there is no need to ‘echo’ single_term_title( $prefix, $display ), unless you have the $display parameter set to false.