RSS

Finding a Category Ancestor / Descendant for WP Templates

Recently I had a problem where I needed to find out if a specific category was a descendant of another category, or if one category was a ancestor of another. The latest website I am working on has a top level category called “Trips we do” and below that are many sub-categories and sub-sub categories etc. I wanted to use the same template on all of the categories that were descended from the “Trips we do”.
Wordpress already has a function that returns the parent categories get_category_parents but this returns a string more suited for breadcrumbs. I needed a yes or no answer that my category in question was in fact descended from some other arbitrary category. Here is the function I produced:

function is_ancestor_cat($ancestor, $descendant){
  $ancestor = (string) $ancestor;
  $desc_id = (string) $descendant;
  $child_cats = get_term_children( (string) $ancestor, 'category');
  if($ancestor == $descendant){
    return true;
  }
  else if(!count($child_cats)){
    return false;
  }
  else{
    $is_child = false;
    foreach($child_cats as $cat_id){
      if($cat_id == $desc_id){
        $is_child = true;
        break;
      }
      else{
        $is_child = $is_child || is_ancestor_cat($cat_id, $descendant);
      }
    }
    return $is_child;
  }
}

What this code does is that is grabs all the children for the ancestor category then checks them against the descendant category, it will keep recursing until it hits the leaf nodes and returns a boolean value.
Here it is in action in my template file category.php:

//Check if we are in a category
if(is_category()){
  $ancestor_cat_id = 43;
  //Lets get the current category we are in
  $cur_cat_id = get_cat_id( single_cat_title("",false) );
  $is_ancestor = false;
  //Check if we are in the ancestor category
  $is_ancestor = is_ancestor_cat($ancestor_cat_id, $cur_cat_id);

  //If it is an ancestor, use a specific template
  if($is_ancestor){
   include(TEMPLATEPATH.'/category-43.php');
  }
  //Use the default template
  else{
   include(TEMPLATEPATH.'/category-default.php');
  }

}
  • Share/Bookmark

Related posts:

  1. Make an Awesome functions.php File For You New Wordpress Template – Part 1 Its been awhile since I threw up a new blog...



6 Responses to “Finding a Category Ancestor / Descendant for WP Templates”

  1. Daniel says:

    Good work Adrian! Just one question; is it possible to modify this function to allow more than one ancestor_cat_id? Per example: if is ancestor of cat ID 43, include one file, if is ancestor of cat ID 80 include another file. Sorry I’m not a coder :-) Thanks!!

    • Yes just run the code twice, something like this:
      if(is_category()){
      $ancestor_cat_id_1 = 43;
      $ancestor_cat_id_2 = 44;
      //Lets get the current category we are in
      $cur_cat_id = get_cat_id( single_cat_title("",false) );
      $is_ancestor_1 = false;
      $is_ancestor_2 = false;
      //Check if we are in the ancestor category
      $is_ancestor_1 = is_ancestor_cat($ancestor_cat_id_1, $cur_cat_id);
      $is_ancestor_2 = is_ancestor_cat($ancestor_cat_id_2, $cur_cat_id);
      //If it is an ancestor, use a specific template
      if($is_ancestor_1){
      include(TEMPLATEPATH.'/category-43.php');
      }
      else if($is_ancestor_2){
      include(TEMPLATEPATH.'/category-44.php');
      }
      //Use the default template
      else{
      include(TEMPLATEPATH.'/category-default.php');
      }

      }

  2. Daniel says:

    Thanks a lot Adrian!

  3. Hellen says:

    Huge thanks!! This is exactly what I was trying to do. But the only ancestor test I found on my own was the cat_is_ancestor_of function in the WP Codex at http://codex.wordpress.org/Function_Reference/cat_is_ancestor_of. And I was having a horrible time getting it to work. You just made my template writing life sooooo much easier!

  4. I’m looking desperatly for a way to check if the _currently_ displayed category is a child of a certain category.

    Can this function be used to achieve that?
    As far as I understand it, it only checks 2 specific categories right?

Leave a Reply