In a site I'm developing, I have the following category structure:

* movies (parent)
    * thriller (child)
    * comedy (child)
    * drama (child)

The current post is in the comedy category. The has_term function with the following parameters returns true:

has_term( 'comedy', 'category' )

But, the same function with the following parameters returns false:

has_term( 'movies', 'category' )

My question is, is there a core function to check if the current post is in any child category of a specific parent category? If not, how can I check this?

Thanks in advance


Add the following to your theme's functions.php:

 * Tests if any of a post's assigned categories are descendants of target categories
 * @param int|array $cats The target categories. Integer ID or array of integer IDs
 * @param int|object $_post The post. Omit to test the current post in the Loop or main query
 * @return bool True if at least 1 of the post's categories is a descendant of any of the target categories
 * @see get_term_by() You can get a category by name or slug, then pass ID to this function
 * @uses get_term_children() Passes $cats
 * @uses in_category() Passes $_post (can be empty)
 * @version 2.7
 * @link http://codex.wordpress.org/Function_Reference/in_category#Testing_if_a_post_is_in_a_descendant_category
if ( ! function_exists( 'post_is_in_descendant_category' ) ) {
    function post_is_in_descendant_category( $cats, $_post = null ) {
        foreach ( (array) $cats as $cat ) {
            // get_term_children() accepts integer ID only
            $descendants = get_term_children( (int) $cat, 'category' );
            if ( $descendants && in_category( $descendants, $_post ) )
                return true;
        return false;

Use the function to check the parent category ID, not name or slug. I.e. if the 'movies' category ID is 50:

if ( post_is_in_descendant_category( 50 ) ) {
    // do something

If you don't know the 'movies' category ID, you could retrieve the ID using get_term_by() and pass it to post_is_in_descendant_category():

$category_to_check = get_term_by( 'name', 'movies', 'category' );

if ( post_is_in_descendant_category( $category_to_check->term_id ) ) {
    // do something
  • Thank you. This should be a built-in wordpress function. – David Rhoden Sep 6 '20 at 19:07

If you want any nesting depth, use get_posts.

 * Checks if the post is in one of the categories or any child category. 
 * @param  int|string|array $category_ids (Single category id) or (comma separated string or array of category ids).
 * @param  int              $post_id      Post ID to check. Default to `get_the_ID()`.
 * @return bool true, iff post is in any category or child category.
function is_post_in_category( $category_ids, $post_id = null ) {
    $args = array(
        'include'  => $post_id ?? get_the_ID(),
        'category' => $category_ids,
        'fields'   => 'ids',
    return 0 < count( get_posts( $args ) );

You can expand on this function in many ways. Maybe pass an array of post ids and filter out some or allow the query to be refined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.