
Here is another great WordPress function to test if you are in a subcategory or the actual parent category and if so return true. This function is pretty much identical in concept to the is_page_or_sub() function I released previously. However, it just tests categories and not pages. Also, the code is significantly different since there are a few more available pre existing function we can build upon here.
For example, the cat_is_ancestor_of() function comes in really handy and does a lot of the heavy lifting for this simple but very powerful function. I use this very function to build complex category based navigation and test for active states and use the appropriate CSS in the change we’re actually in one of the categories we’re testing for. If you have question feel free to ask by commenting below and enjoy mastering WordPress!
The Function
1 2 3 4 5 6 7 8 9 | // If is category or subcategory of $cat_id if (!function_exists('is_category_or_sub')) { function is_category_or_sub($cat_id = 0) { foreach (get_the_category() as $cat) { if ($cat_id == $cat->cat_ID || cat_is_ancestor_of($cat_id, $cat)) return true; } return false; } } |
Sample Usage
1 2 3 4 5 | if (is_category_or_sub(1)) { DISPLAY SOMETHING } else { DISPLAY SOMETHING DIFFERENT } |
Donations
- Make a donation and help keep the awesomeness flowing.
Disclaimer
Valen Designs grants you a nonexclusive copyright license to use all programming code examples from which you can generate similar function tailored to your own specific needs.
Valen Designs, cannot guarantee or imply reliability, serviceability, or function of these programs.
All programs contained herein are provided to you "AS IS" without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.



Comments
“Hi again.
It works fine if I test for one category. I have between 4-6 categories on each page and I would like to test for all of them in one statement. ( If this post belongs to cat 13 or 14 or…or 17, then return true)
I tried in a few different ways without success. Is it possible?
I really appreciate you taking the time!!!”
@chris Jangelov: You can test multiple categories at one time no problem, that is what this function does. First are all these categories children of one parent caregory? If so you just need to pass in the id of the parent category and the function will return true.
For example,
if (is_category_or_sub(13) { echo ’something’; }
However, if you are testing just random categories and not parent child relationships all you need to do is:
if (in_category(13) || in_category(15)) { echo ’something’; }
hi
does it work also with category-slugs?
thank you
I found this technique to work with slugs, this also works for sub categories that may have the same name as the parent category. For example, having an Audio category within a category also called Audio. This is when using the slug can come in handy.
in_category(‘audio-audio’)
Very simple. Hope it helps!
Derek,
You made my day. I had no idea that I could test for category outside the loop so I never tried that. Went for pageID instead.
As you supposed it was enough with the in_category function.
Thank you very much for your help. May your life be long and happy!
Always glad to help and good luck with your project.
Works great, thank you
Awesome, glad to hear it.
Thanks for this function. Works great! Do you have a “donate” button? Would like to show my appreciation.
Sure you can donate using the button I added above. Glad it was of use to you!
Thanks heaps exactly what I was looking for!
hi!
sorry i don’t very good in php but your code don’t work good on my site.
i have a category and a subcategory and with your code i can see if i am in category or subcategory true?
i have put this code:
// If is category or subcategory of $cat_id
if (!function_exists(‘is_category_or_sub’)) {
function is_category_or_sub($cat_id = 0) {
foreach (get_the_category() as $cat) {
if ($cat_id == $cat->cat_ID || cat_is_ancestor_of($cat_id, $cat)) return true;
}
return false;
}
}
if (is_category_or_sub(1)) {
echo “DISPLAY 1″;
} else {
echo “DISPLAY 2″;
}
in page archive.php
but i see string “DISPLAY 2″ in booth category and subcategory why?
i have put this code before in archive page.
Can you help me please?where i wrong?
regard erwin
ps sorry my bad english :P
ok i know!
i have add code:
$this_category = get_category($cat);
and modifie the function “is_category_or_sub” with parameter $this_category and this work!!
thx a lot!
:)
good blog
regard
erwin
Trau, for starters you should be putting the function in your functions.php and not in your theme file.
Second, I use this function on almost every site I’ve ever built and it has always worked fine. I’m not sure why you are having difficulty but there is no reason I can think of that you would need to edit the original function.
I’m glad you got it to work anyhow.
HI Derek,
I think Trau’s problem (emphasis on i*I think*, I probably should try it first) might have to do with the categories the current post was assigned to. What I mean is.. when that post was added, it could have been assigned both the parent and child category in the Categories box ( via checking both the parent and child boxes)
Unless that’s the proper way of doing that?
It can’t be, right? However, for example, when if setup my permalink structure as so:
/%category%/%postname%/
I end up with the permalink of my child category posts showing only the parent category while /%category%/ is supposed generate the nested directory for the sub category.
-C
To clarify, the function says return true if parent OR child. So, it doesn’t matter if you have both of them checked off or not.
Hi Derek,
Thanks for providing this solution.
You should submit it to WP because it is a valuable and quite used function. For me, you saved the day !!!
Kudos!
Works like a dream, thanks :)
Thank you! It worked perfectly!
I LOVE YOU!!!!! This is exactly what I need! Thank you very much!!
Great function! this is what I need! Many thanks! :)
Hi!
This function is great but however not acts exactly what it
should, I guess.
Let’s have this scenario. We have a website and in the sidebar for a main category and all its subcategories we need to display something, let’s say the text: “Good morning Vietnam!”(but only for category and subcategories sections page, not for the posts belonging to these main category or subcategories).
Something likes this:
http://www.domain.com/category sidebar text “Good morning Vietnam!”
http://www.domain.com/category/sub-category sidebar text “Good morning Vietnam!”
http://www.domain.com/category/sub-categories/post-title —> I don’t want any sidebar text!!! (Function failed, function still displays sidebar text “Good morning Vietnam!”)
The function display the text on each and every post that belongs to main-category or sub-categories- FAIL!
Anybody can point me to the right direction?
Thanks!
I found the solution:
if (is_category_or_sub(1) && ! is_single())
{
echo “Good morning Vietnam!″;
} else {
echo “″;
}
Thanks for this function.
to Check for a Category or Subcategory (Using the Slug)
http://www.jeangalea.com/wordpress/check-category-subcategory-slug/
Thank you so much!
Would it be possible to do something like this:
(is_category_or_sub(Highest Level Category ID In the current hierarchy))
In other words, We have 5 root level categories, each of those 5 have 5 subcategories and each of those have another 5 sub SUBcacegories. Would it be possible to retrieve the root level’s subcategoreis and display those on a single page.
Hope that makes sense!
Thanks again
Dude, huge thank’s, this is what i was needing, im glad i found your website, thank you thank you thank you ;)
Derek, is it possible to have multiple ids in the function? like is_category_or_sub(‘20,7′)
Thank you
Sorry, it’s not set up for arrays. It could be though.
Great code!
but in some how one of my category was messing when is_home so because I didn’t have enough at the moment I had to hack it by putting is_category_or_sub() && !is_home().
That worked as a charm.
thank you! you made my day!
Spot on! Thanks.
Trackbacks