I have found the following piece of code in the WP Knowledge Base theme in order to show subcategories of a parent category. The problem is that this only works for the first level of hierarchy, so I wanted to change the if clause in order to check if the current category has children but I have no clue how to do that, any idea? Thanks

global $term_meta, $cat, $cat_id, $wp_query;

// Check if the current category is not a first level category
// This will happen if the current category does not have any child
// If this is the case, then we simply show all it's posts
// Instead of the nice knowledgebase type things
if ( $cat->parent != '0' ) {

5 Answers 5


You could use this simple function call which returns either TRUE or FALSE depending on if $children is an empty array or not.

 * Check if given term has child terms
 * @param Integer $term_id
 * @param String $taxonomy
 * @return Boolean
function category_has_children( $term_id = 0, $taxonomy = 'category' ) {
    $children = get_categories( array( 
        'child_of'      => $term_id,
        'taxonomy'      => $taxonomy,
        'hide_empty'    => false,
        'fields'        => 'ids',
    ) );
    return ( $children );

So if you're only using the built-in post categories you can call the function like so: category_has_children( 17 );

If you need to test a custom taxonomy it will work almost the same, you'll just need to pass in an extra parameter 'taxonomy-slug': category_has_children( 7, 'my_taxonomy' );'

To call it in your IF statement:

if( $cat->parent != 0 && ! category_has_children( $cat->term_id ) )
  • 1
    get_term_children() already does what the OP wants. It is just a matter of creating a boolean conditional tag :-) Commented Jun 24, 2015 at 7:39
  • 1
    Just a note, the type parameter is not meant for post_type, but rather whether or not the category is from the build in taxonomy category or the build in taxonomy link_category. This parameter was used before the introduction of custom taxonomies in version 3.0. The type parameter have been depreciated for the new taxonomy parameter that was introduced in version 3.0. Current source code Commented Jun 24, 2015 at 8:21
  • Note: On Woocommerce the $taxonomy needs to be changed to 'product_cat' instead of 'category'
    – luissimo
    Commented Aug 20, 2020 at 19:25

There is a build in function for this already, no need to create a custom function for this. The function is called get_term_children() and will return either

  • An array of child terms if the given term have children

  • An empty array if no child terms are found

  • WP_Error object if the taxonomy does not exist

With this in mind, wrap get_term_children() in a function and return true or false depending on the returned value if you just need a boolean value ( like a conditional tag )

function has_term_have_children( $term_id = '', $taxonomy = 'category' )
    // Check if we have a term value, if not, return false
    if ( !$term_id ) 
        return false;

    // Get term children
    $term_children = get_term_children( filter_var( $term_id, FILTER_VALIDATE_INT ), filter_var( $taxonomy, FILTER_SANITIZE_STRING ) );

    // Return false if we have an empty array or WP_Error object
    if ( empty( $term_children ) || is_wp_error( $term_children ) )
    return false;

    return true;

You can simply now just pass the term id to the function and the correct taxonomy name if the taxonomy is anything other than category, and you will get a boolen value back just as the build in conditional tags, true on success if the term have children, false if it does not.

if ( has_term_have_children( 21 ) ) {
    // Do something if term 21 have children
  • You could also do if ( has_term_have_children( get_cat_ID() ) ) on the category page Commented Oct 30, 2015 at 13:03
  • @AndrewLazarus true, the exact use case depends on your setup and what you exactly need. Unfortunately, when I answer questions, I cannot cover all bases, and sometimes miss one or two things. Comments like you have posted is always much appreciated and encouraged ;-). Enjoy Commented Oct 30, 2015 at 15:08
  • @AndrewLazarus you can also use get_queried_object_id() instead of get_cat_ID() on a category page ;-) Commented Oct 30, 2015 at 15:09

To get the name of the child categories. I have used @Howdy_McGee's function for a quicker & iterative process.

function category_has_children( $term_id = 0, $post_type = 'post', $taxonomy = 'category' ) {

    $children = get_categories( array( 'child_of' => $term_id, 'type' => $post_type, 'taxonomy' => $taxonomy, 'order' => 'ASC', 'orderby' => 'name' ) );
    echo '<ul>';
    foreach ($children as $value) {
        echo '<li>';
            echo '<a href="'.get_bloginfo("siteurl").'/category/'.$value->slug.'" >'.$value->name.'</a>';
        echo '</li>';
    echo '</ul>';

$cId = get_cat_id('cms'); /* cms is the parent category */
category_has_children($cId, 'post', 'category');

This will list all the sub-category (child) of a parent category.

  • 1
    WordPress already has a built-in function that does this: wp_list_categories()
    – Howdy_McGee
    Commented Jan 29, 2015 at 15:00
  • Yes, but customizing/ structuring is bit strict with that. :)
    – Shreyo Gi
    Commented Jan 30, 2015 at 2:45

This is what I use. The variable $cat is the category ID you are checking:

$categories = get_categories($cat);

if (!empty($categories)) {
    // This Category has children
else {
    // This category has no children

Use this function cat_has_subcat('paste cat id') to check the category has any subcategories or not

//paste it in your function.php


function cat_has_subcat($catId){
    $args = array(
        'taxonomy' => 'product_cat',
        'orderby' => 'name',
        'parent' => $catId,
        'show_count' => 0,
        'pad_counts' => 0,
        'hierarchical' => 1,
        'title_li' => '',
        'hide_empty' => false

    $cats = get_categories($args);
        return $catId;

  • Some explanation why this would solve op's question would be nice.
    – cjbj
    Commented Nov 9, 2017 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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