Learn when to use has_term(), is_tax(), and helper functions for parent and child taxonomy checks in WordPress.
EN

Check if a post belongs to a taxonomy term

5.00 /5 - (24 votes )
Last verified: May 1, 2026
4min read
Tutorial
Full-stack developer

A common task for a developer is to display an element (e.g., an ad banner) only if the post belongs to a specific category or taxonomy (e.g., ‘Movie Genre: Comedy’).

In WordPress, we have two main functions for this that are often confused: is_tax() and has_term(). The difference between them is crucial for your theme’s logic.

If you want the short version first, use is_tax() to check the current archive page, and use has_term() to check whether a specific post is assigned to a term.


#1. is_tax() vs has_term() - What’s the difference?

#is_tax() - Page context (archive)

Use this to check what page the user is viewing.

  • Is the user currently on the “Horror” category archive page?
if ( is_tax( 'genre', 'horror' ) ) {
    echo 'You are on the Horror list!';
}

This function will return false if you are on a Single Post page, even if that post is actually a horror movie!

#has_term() - Post context (single)

Use this to check what is assigned to a specific post.

  • Is this specific movie a “Horror”?
if ( has_term( 'horror', 'genre' ) ) {
    echo 'This post is a horror movie.';
}

This function is most often used inside The Loop or in the single.php file.


#2. The hierarchy problem (parents and children)

The biggest challenge is that has_term() only checks exactly the term you specify.

Assume this structure:

  • Movies (Taxonomy: movie_genre)
    • Comedy (ID: 10)
      • Romantic (ID: 11)
      • Dark Comedy (ID: 12)

If you have a post assigned ONLY to “Romantic”, checking:

has_term( 'comedy', 'movie_genre' ) 

will return FALSE. Why? Because the post technically doesn’t have the “Comedy” checkbox checked, only “Romantic”.

#Solution: Helper function for descendants

To check if a post belongs to “Comedy” OR any of its subcategories, we need to write our own helper function.

/**
 * Checks if a post belongs to a term or its children.
 *
 * @param int|string|array $term_id_or_slug ID or Slug of the parent term.
 * @param string $taxonomy Taxonomy name.
 * @param int|null $post_id Post ID (optional).
 * @return bool
 */
function wppoland_in_term_tree( $term_id_or_slug, $taxonomy, $post_id = null ) {
    $post_id = $post_id ? $post_id : get_the_ID();
    $term    = get_term_by( is_numeric($term_id_or_slug) ? 'id' : 'slug', $term_id_or_slug, $taxonomy );

    if ( ! $term ) {
        return false;
    }

    // 1. Check direct assignment (fastest)
    if ( has_term( $term->term_id, $taxonomy, $post_id ) ) {
        return true;
    }

    // 2. Get all children of the term
    $children = get_term_children( $term->term_id, $taxonomy );
    
    if ( is_wp_error( $children ) || empty( $children ) ) {
        return false;
    }

    // 3. Check if the post has any of the children
    return has_term( $children, $taxonomy, $post_id );
}

#Usage:

// In single.php
if ( wppoland_in_term_tree( 'comedy', 'movie_genre' ) ) {
    get_template_part( 'partials/banner-comedy' );
}

Now this works for both “Comedy” and “Romantic Comedy”.


#3. Performance optimisation

The get_term_children() function performs a database query. If you use this in a loop displaying 50 posts, you are making 50 extra SQL queries.

How to optimise? If your category structure rarely changes, you can cache the children IDs in the Transients API. For most smaller projects that is optional, but it becomes more useful when the same helper runs repeatedly across larger templates or loops.

A more important optimization is passing the ID instead of the Slug. WordPress has to look up the ID from the Slug anyway, so providing the ID (e.g., 10) saves one lookup query.

// Faster (ID)
has_term( 10, 'movie_genre' );

// Slower (Slug -> requires lookup)
has_term( 'comedy', 'movie_genre' );

#Summary

Learn more about professional WordPress development at WPPoland.

  1. Use is_tax() only to check if you are on an archive page.
  2. Use has_term() to logically check individual posts.
  3. Remember that has_term doesn’t inherit – if you need “category and its children” logic, use a custom helper function.

This is the foundation of building dynamic themes that react to content context.

Next step

Turn the article into an actual implementation

This block strengthens internal linking and gives readers the most relevant next move instead of leaving them at a dead end.

Want this implemented on your site?

If you want to convert the article into a working site improvement, redesign, or build plan, I can define the scope and implement it.

Related cluster

Explore other WordPress services and knowledge base

Strengthen your business with professional technical support in key areas of the WordPress ecosystem.

Article FAQ

Frequently Asked Questions

Practical answers to apply the topic in real execution.

SEO-ready GEO-ready AEO-ready 3 Q&A
What is the difference between has_term() and is_tax()?
has_term() checks whether a specific post is assigned to a term, while is_tax() checks the current archive page context. They solve different problems and should not be used interchangeably.
How do I include child terms in my check?
You usually need a helper that expands the parent term with get_term_children() and then checks the post against that full term tree.
Should I use IDs or slugs for taxonomy conditionals?
IDs are usually a little more efficient and less fragile, especially in larger projects or where slugs may change during localisation.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss

Related Articles

The get_post_meta() function is foundational. Learn how to fetch, display, and manage custom field data in your theme. Advanced guide for developers.
development

How to display custom field values in WordPress (2026 guide)

The get_post_meta() function is foundational. Learn how to fetch, display, and manage custom field data in your theme. Advanced guide for developers.

Stop writing messy if-statements. Learn the difference between in_category and has_term, how to handle recursive child categories efficiently, and optimize your conditional tags.
development

WordPress conditional logic for taxonomies

Stop writing messy if-statements. Learn the difference between in_category and has_term, how to handle recursive child categories efficiently, and optimize your conditional tags.

Practical notes on WP_Query: when get_posts beats new WP_Query, why meta_query on unindexed keys collapses at scale, and how to paginate custom loops without hitting 404s.
development

A working guide to WP_Query and the loop (2026 performance edition)

Practical notes on WP_Query: when get_posts beats new WP_Query, why meta_query on unindexed keys collapses at scale, and how to paginate custom loops without hitting 404s.