WordPress: Get ID of top-level parent category

I wanted to get the ID of the top level parent category of the current category such that, if the current category was a child of a child category (or any number levels down), I would have the top-level category ID returned to me. This post showing how to get the parent category ID sent me in the right direction and I’ve developed it a bit to fulfil my requirements.

It was also important that if I was browsing a top-level parent category, then I would just get the current category ID. The following function does the work in a nice simple fashion. All you need to do is feed it the current category ID.

The Function

/**
* Returns ID of top-level parent category, or current category if you are viewing a top-level
*
* @param	string		$catid 		Category ID to be checked
* @return 	string		$catParent	ID of top-level parent category
*/

function pa_category_top_parent_id ($catid) {

 while ($catid) {
  $cat = get_category($catid); // get the object for the catid
  $catid = $cat->category_parent; // assign parent ID (if exists) to $catid
  // the while loop will continue whilst there is a $catid
  // when there is no longer a parent $catid will be NULL so we can assign our $catParent
  $catParent = $cat->cat_ID;
 }

return $catParent;
}

Usage

Obviously this function can be used in a variety of locations, but if you were checking things in your category.php template file you would use it as follows. In the case below I’m just echoing the top-level parent category ID.

$catid = get_query_var('cat');
echo pa_category_top_parent_id ($catid);

I hope someone finds this useful!

Comments

  • Yep ! This was very usefull for my other WP site, as I needed to style the subcategory pages as the top level category.

    Thnx, man ! Saved my day !

    • Hi Alen,

      Delighted this was of use to someone. I'm trying to remember to post little functions and tweaks for WordPress whenever I work something out. I don't know where I'd be without the huge amount of how-to's and hints published by WordPress developers around the world. Feels very good to give some of that back!

      Thanks for dropping the comment 🙂

  • Yeah, I was thinking the same – I really should share all that knowledge that was so generously given to me … I really must do blog with such codes and stuff… To see your code in action visit http://mastercatering.hr – this piece of code is involved in css styling of categories and subcategories …

    Anyway, thanks again

  • I have also found it very useful to have make these notes for my own recollection. Over the years you write so many functions that it's hard to keep track of them all. What better than a little category on your own blog which contains all these little features 🙂

    I was using the this function not for CSS styling, though I can see it as being wholly useful for that. I needed it as a way to ensure the same sub-menu in a sidebar was loaded no matter which sub-category you were on.

    Good work on the site and thanks again for letting me know the code was useful!

  • Sergey

    Thank you very very much!

    It' just what I was looking for and found only here.

    Very short and genius code.

    • Hey Sergey,

      Very happy to hear that it helped you as well!

      The inspiration for this looping method to keep getting the parent cats came from this WordPress.org forum thread and I modified it to suit my needs. So props out again to Ivovic. That single WordPress forum thread taught me an awful lot about WordPress manipulation – and I'm still utilising those methods regularly 🙂

      Thanks for commenting!

  • Pingback: Alex Barber | Digital Artist | WordPress – Get top level parent category()

  • Orijit

    Just what I was looking for. Neat.

  • M. Des

    Hello.
    I wanted to thank you for the code – I am a “” begginer and even so I did manage to put the code in the right place and use it the way I need and it WORKS! yesssss :-))
    So if I can help someone this is how I used it – first I put the above code for the function into my functions.php .
    Then:
    – in my category.php file I was checking:

     if category’s parent is category with ID=26 —> then use template cat-pov.php
     if parent category has ID=12 —> then use template cat-soc.php
     for all other use —> template cat-default.php

    Here is the code I put into category.php:

    So far it is working exactly as I expected – hopefully I will make someone happy with this code :-))

    Best regards,

    • M Des

       hmm – I don’t see my code..here it is again:

      $catid = get_query_var(‘cat’);
      $id = pa_category_top_parent_id ($catid);
      switch($id)
      {
        case 26:
          include(TEMPLATEPATH.’/cat-pov.php’);
          break;
        case 12:
          include(TEMPLATEPATH.’/cat-soc.php’);
          break;
        // and so on
        default:
          //the default template
          include(TEMPLATEPATH.’/cat-default.php’);
          break;
       }

      • Hey there, delighted to hear my code helped out and that’s exactly the sort of usage I could see it being helpful for.

        You could also do, instead of using TEMPLATEPATH

        switch ($id) {
        case 26:
        get_template_part(‘cat’, ‘pov’);
        break;
        // etc
        }

        It’s exactly the same but I find it a little neater (and you can sometimes run into issues with include statements on certain server configurations).

        Thanks dropping by with a comment, always nice to hear that these functions are useful to people.

        Cheers,
        Alex

        • M Des

           Thanks for advice, who knows when I will need it. 🙂

  • M Des

    Hello again,
    I have a question: the code I posted before was working for my category.php.
    I have the similar situation when displaying single post.
    If post is for example category 14 and category with id=14  has a parent category with id=26 ,
    then for this post I want to use template single-pov.php  etc.

    So I was checking the parent of a posts category.
    I was trying to use your function and similar switch-case method in single.php.

    For some reason it was not working at all – everything fall down to single-default.php.

    Since I am a beginer I am sure I did some stupid mistake, my guess is I should use the right query to get single post category-right? … since it is “the post” we are talking about not “category” probably code HAS to be different – if you can find what was wrong I would be very greatful
    Here is the code I use in single.php:

    $catid
    = get_query_var(‘cat’);

    $id=
    pa_category_top_parent_id ($catid);

    switch($id)

    {

    case
    10:

    include(TEMPLATEPATH.’/single-fotogalerija.php’);

    break;

    case
    26:

    include(TEMPLATEPATH
    .’/single-povijest.php’);

    break;

    //
    and so on

    default:

    //the
    default template

    include(TEMPLATEPATH.’/single-default.php’);

    break;

    }

    I am confused with wordpress codex , I found     get_the_category( $id )   –  but I really don’t know the right way to use it, the sintax which will get me a parent category as a result ..please help….

    • This code will only work when you are viewing a category, not a single post or a page or a custom post type.

      The issue with trying to determine parent category for a single post is that a single post _can_ reside in more than one category.

      If you know for certain that you’re only ever going to apply one category to each post then you can use the get_the_category() function in your single.php file.

      http://codex.wordpress.org/Function_Reference/get_the_category

      You would probably need to do something like


      $category = get_the_category($post->ID);
      $catid = $category[0]->cat_ID;
      $top_level_cat =
      pa_category_top_parent_id ($catid);

      Or something along those lines. Hope that helps!

      • M Des

        I did try something similar and it was working only for posts which category has parents.
        For those that had no parent it was falling down od default even if I was determine the case.
        For example I have a category id=10, no parent,  and would like to display posts from that category with single-special.php.
        But it was falling to default.
        I’ll try with your code (mine was slightly different and probably wrong … heh)…
        Had to finish something first so I’ll post results soon as I get to it… thanks

  • Brk Aydn

    you make my day! thank you much!

    • You’re most welcome! Glad the code was useful 🙂

  • Hardik Patel

    Thanks

  • Gackan

    Nice post. I made a slight mod to list the category name instead of the category ID:

    function pa_category_top_parent_id ($catid) {
    while ($catid) {
    $cat = get_category($catid);
    // get the object for the catid $catid = $cat->category_parent;
    // assign parent ID (if exists) to $catid
    // the while loop will continue whilst there is a $catid
    // when there is no longer a parent $catid will be NULL so we can assign our $catParent
    $catParent = $cat->cat_ID;
    $catParentName = get_cat_name($catParent);
    }
    return $catParentName;
    }

    • Cool – I can see how that could be useful 🙂

      A!

  • mikonaiko

    thank you! been looking for this.

  • Ozair

    Great Post..it really useful for me.. 🙂

  • Ozair

    on post page category it is not working.?

    • What is the name of the template file? That would help me know what’s up.

  • Michelle

    Man, Big ths!!!

  • You best! Thanks ))

  • Would this work? Basically you pass in your category id, and it uses get_ancestors() to get the array of ancestor ids and then uses array_pop() to get the last one – the parent. If there are no ancestors, then the cat is already the parent, and it’s returned:

    function get_root_category_by_id($cat_id)
    {
    $ancestors = get_ancestors($cat_id, ‘category’);
    return count($ancestors)>0?array_pop($ancestors):$cat_id;
    }