Get Categories for Custom Post Types and Taxonomies

I recently built my own basic downloads manager plugin because I wanted something stupid simple. The bare functionality I needed was the title, a description, the file, and categories — So, I created a custom post type and then added a few meta boxes with the Custom Metaboxes and Fields Class.

I wrote all of the above in less than 10 minutes. The problem  I then encountered was figuring out how to get the list of categories that a download was assigned to.

This is simple when just working with regular posts; Just use the get_categories() function. However, categories within custom post types are a different beast…

Custom Post Types DO NOT Have Categories

I spent hours trying to figure out how to get the categories from a custom post type. And you know what I figured out after all of that wasted time? That custom post types do not have categories…

You see, categories are a type of taxonomy that is built-in to WordPress and used to categorize posts. When we create a “category” for a custom post type, we are actually creating a completely new taxonomy (even though we may in fact call it ‘categories’).

Take this custom taxonomy example below:

function cw_cpp_slideshow_categories() {
    $field_args = array(
        'labels' => array(
            'name' => 'Categories', 'taxonomy general name',
            'singular_name' => 'Category', 'taxonomy singular name',
            'search_items' => 'Search Categories',
            'all_items' => 'All Categories',
            'parent_item' => 'Parent Category',
            'parent_item_colon' => 'Parent Category:',
            'edit_item' => 'Edit Category',
            'update_item' => 'Update Category',
            'add_new_item' => 'Add New Category',
            'new_item_name' => 'New Category',
            'menu_name' => 'Categories',
        'hierarchical' => true
    register_taxonomy( 'slideshow_categories', 'slideshow', $field_args );
add_action( 'init', 'cw_cpp_slideshow_categories', 0 );

This is some code that I use to add categories to a slideshow custom post type. Look specifically at the line where I call register_taxonomy() . Notice how I define the taxonomy as slideshow_categories , then assign it to post type slideshow , then I pass in various arguments, such as labels, in the 3rd parameter.

So, while I created a taxonomy that looks and functions almost exactly like categories does with posts… I actually created a new taxonomy named slideshow_categories .

Confusing? Yea, a bit…


Well, here’s a little bit more confusion. You know what you usually call categories? Those are actually named terms in other taxonomies…

 So, How Do I Get Categories for Custom Post Types?

The answer is pretty simple — just use get_terms(). The only parameter you need to pass in to get_terms()  is a taxonomy name, slideshow_categories from the example above.

But, if you need to do some special ordering, excludes, etc… You can also pass an array of arguments as the second parameter. Check out the codex for get_terms().

Questions or Comments?

If this helped you or if you just find it funny how long it took me to figure this out… leave comment below!

24 responses to “Get Categories for Custom Post Types and Taxonomies”

  1. You have no idea how this just saved my sanity.
    It took me all freaking day trying to retrieve the categories of a custom post type. This is insane, and to me is just illogical that wp manages this in that way.

    I glanced at my database, specifically in wp_term_taxonomy table, and there it was.

    Anyway, thanks a lot !

    1. Hey Fernando,

      Glad to hear that!

      I do remember for frustrated I was when I tried figuring out how to do this. At least it’s working now 🙂

  2. Hey man, sorry to bug ya. I am somewhat running into the same issue you had, but mine is a little bit different. I am able to pull in posts under a custom post type (in a list) and have those posts bucketed into the various categories that is shared with other posts (not post-types). I am now needing to take that a level deeper and now show the child categories in the buckets and have its posts listed under that category. If you have time maybe you could give some guidance on how I can achieve this. Here is the paste bin to that: Again only if you have time. Thanks in advanced.

    1. I’m having a bit of an issue putting together the entire picture. I’d be glad to take a look at it if you have a staging environment that I can take a look at. You can email this to me through my Contact Form.

      P.s. – I like your portfolio website.

  3. Thank you. You just saved me a lot of time. :o)

  4. Excellent. Just saved me a bunch of time I’m sure.

    1. Hey Josh, thanks for leaving a comment and letting me know the post was helpful!

  5. Thank you so much! 2 days searching until you save me…

    1. Thanks Jairo! I’m glad you found it useful 🙂

  6. Thanks for simple understanding post 🙂

    just need some help. I have created custom post type and registered taxonomy. But on post edit page sidebar of custom post type, I have no option to choose or add category. Instead, I have sidebar to add tags there.

    1. Would you mind sharing the code that you used to create the custom post type and taxonomy? Preferably through a Github Gist or a Pastbin link. Alternatively, if you don’t want the code public, please email it to me through the contact form.

  7. Got the solution!

    I had set hierarchical to false instead of true.

    May help someone. 😉

    1. Thanks for circling back and mentioning what solved your problem

      1. Thanks for good blog and your quick response.

  8. Here’s what works:

    function get_cpt_parent_cat_aka_taxonomy() {
    global $post;
    $parent_tax_name = ‘Undefined parent taxonomy!’;
    $obj_taxonomies = get_object_taxonomies( $post->post_type, ‘objects’ );
    $slugs = array();
    if( !empty( $obj_taxonomies ) ) {
    foreach ( $obj_taxonomies as $key => $tax ) {
    if( $tax->show_ui === true && $tax->public === true && $tax->hierarchical !== false ) {
    array_push( $slugs, $tax->name );
    $terms = wp_get_post_terms( $post->ID, $slugs );
    $term = get_term( $terms[ 0 ]->term_id, $terms[ 0 ]->taxonomy );
    $parent_tax_name = $term->name;
    return $parent_tax_name;

    1. Thanks for the example code Dameer. I went ahead and modified it slightly to allow for syntax highlighting.

      It looks like your code returns a taxonomy, which is equivalent to a grouping of terms. Once the taxonomy was found, I believe the user would still want to use get_terms() to return the terms, or what most people consider categories, for that taxonomy.

  9. Thanks for the awesome post – it all makes sense now!

    When I do get_terms(‘taxonomy’); I get an output of “array”.

    Where taxonomy is my CPT taxonomy name.

    Im looking into it now but any advice would be appreciated

  10. Aawesome post you save my day, Eric Binnion 🙂

    1. Hey Savan –

      I’m glad to hear that. Thank you for leaving a comment and letting me know!

  11. You explain how to get terms from a custom taxonomy assigned to a custom post type but what about URLs ?

    If you create the following structure :

    Custom taxonomy “catalog_categories”
    – term 1
    — term 1.1
    — term 1.2
    – term 2

    Custom post type “catalog”
    – my item 1 (selected term : term 1.2)

    The URL of “my item 1” will be and not

    So what you explain is not a copy of built-in posts and categories.

    If you have any idea on how I can do this 🙂

  12. Thank you for straightening me out on that mental hurdle. The semantics of it matter to me probably more than they should. I’ve done this several times, created “categories” for custom post types but I’ve been referring to them as categories incorrectly.

    Let me ask you this though: if you have more than one custom post type are you one of those “put them all in one admin menu branch” thinkers or “put them in separate admin menu branches” thinker?

    1. I’d lean towards having separate admin menus. But, it also depends on the use case.

      For example, if I’m creating two separate post types on my personal blog – One for locations that I’ve been and another for my favorite books – Then those would be separate.

      However, if I were to create some post types that had a similar interest – For instance, tracking my progress in shooting sports by having a training journal post type, a competition post type, and an equipment post type – Then I might group them together under a menu item that made sense.

  13. Thank you a million times, I have been banging my head against a brick wall all day trying to work this out. Used it to add EDD Download categories to a filter menu in wordpress. Not quite finished the whole process but your revealtion has got me a step closer.


  14. Thank you! You saved me hours of trouble and this was a very clearly written overview custom taxonomies.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.