I’m attempting to make an archive template that will apply only to subcategories of a particular term. My structure looks something like this:
- Events (main taxonomy)
- Tradeshow
- Show subcat 1
- Show subcat 2
- Other taxonomies
- Tradeshow
I want Show subcat 1
and Show subcat 2
(and any other subcategories) to all get the same archive template. This is one of my attempts at it, which is definitely not working. Here’s the code from my functions.php
.
add_filter( 'template_include', 'kd_event_subcategory_archive' );
function kd_event_subcategory_archive( $template ) {
$term = get_queried_object()->term_id;
if ( $term->parent == 'tradeshow' ) {
$event_subcat = locate_template( 'taxonomy-tradeshow-subcategory.php' );
return $event_subcat;
}
return $template;
}
I can’t seem to figure out how to properly check if a term is the child of my tradeshow
term.
2 Answers
There are two problems that have thwarted your check:
$term = get_queried_object()->term_id;
if ( $term->parent == 'tradeshow' ) {
Starting with:
$term = get_queried_object()->term_id;
Here $term
contains the ID of a term, not a term object. Lets assume this is term number 5, the result is:
$term = 5;
if ( $term->parent == 'tradeshow' ) {
Which won’t work. $term
is a number, not an object, so you cant do ->parent
on it.
The fix is to just use the queried object directly:
$term = get_queried_object();
Which leads us to the next problem:
if ( $term->parent == 'tradeshow' ) {
The parent isn’t a string, it’s a term ID. 0
if there is no parent, else it’s the ID of the parent term, as shown if we look up WP_Term
:
/**
* ID of a term's parent term.
*
* @since 4.4.0
* @var int
*/
public $parent = 0;
So you need to acquire the tradeshow term in advance to find out its ID. Usually, for these scenarios, developers will not hardcode the slug, but instead provide a setting that lists terms, and store the ID as an option to avoid this kind of lookup, and increase flexibility
But in this case you can use the get_term_by
function, e.g.
$tradeshow = get_term_by('slug', 'tradeshow', 'events')
Then using:
$tradeshow->term_id === $term->parent
Problems and Advice
These are additional items I wanted to mention that are unrelated
Debugging
Using var_dump
, a debugger, or some other tool to see what the contents of $term
was would have revealed these problems.
Additionally, PHP error logs will be full of warnings and notices pointing at the if statement for trying to do the equivalent of 5->parent
which makes no sense to PHP. Pay attention to error logs. I’d recommend using the query monitor plugin as an easy way to catch unexpected warnings
The Queried object isn’t always a term
This code will run on every page load:
add_filter( 'template_include', 'kd_event_subcategory_archive' );
function kd_event_subcategory_archive( $template ) {
$term = get_queried_object()->term_id;
if ( $term->parent == 'tradeshow' ) {
But what if the user visits a date archive or an author archive? Now the code runs anyway, generating errors. So this filter needs tests to check if the user is on a taxonomy archive, and that the taxonomy matches.
It may even be a singular post, and if the trade show term has a term ID of 5, and you’re on the post or page with ID 5, then you’ll get a post showing on a taxonomy archive.
I suspect though that it would be easier to use a separate taxonomy.
https://codex.wordpress.org/Function_Reference/get_queried_object
- if you’re on a single post, it will return the post object
- if you’re on a page, it will return the page object
- if you’re on an archive page, it will return the post type object
- if you’re on a category archive, it will return the category object
- if you’re on an author archive, it will return the author object
- etc.