Add columns for custom taxonomies to custom post types in WordPress

If you ever found strange that you could edit the terms of a custom taxonomy for a custom post type using the Quick Edit link but you couldn’t see the terms applied in the columns, you’re not alone. That’s why in this tutorial we will learn how to display those terms in the list view for our custom post types.

In the same way that you see Tags and Categories in the posts list view, it is also useful to know which terms have been applied for our custom taxonomies in our custom post types. But even for regular posts, custom taxonomies are now shown. The code below utilizes a fictional custom post type ‘event‘ and a custom taxonomy ‘events‘ and creates a new column in the event list view to display the events custom taxonomy with links for each term to display a filtered view of events. You can add this code in the functions.php file of your WordPress theme or, if you have it, in a dedicated page for the admin.

We first hook a functions to filter the columns and add our own column, and then hook another function to display the taxonomy terms for each event post:

[php]
add_filter( ‘manage_event_posts_columns’, ‘ilc_cpt_columns’ );
add_action(‘manage_event_posts_custom_column’, ‘ilc_cpt_custom_column’, 10, 2);
[/php]

The first function used for filtering is pretty easy, we simply add a new column for our taxonomy and set a label for the column header:

[php]
function ilc_cpt_columns($defaults) {
$defaults[‘events’] = ‘Event Type’;
return $defaults;
}
[/php]

Now, after getting the post terms by its taxonomy, we initialize an array containing all the terms and build the links for each term using the post type and the term slug. If some post doesn’t have any terms, we display a notice:

[php]
function ilc_cpt_custom_column($column_name, $post_id) {
$taxonomy = $column_name;
$post_type = get_post_type($post_id);
$terms = get_the_terms($post_id, $taxonomy);

if ( !empty($terms) ) {
    foreach ( $terms as $term )
        $post_terms[] = "<a href='edit.php?post_type={$post_type}&{$taxonomy}={$term->slug}'> " . esc_html(sanitize_term_field('name', $term->name, $term->term_id, $taxonomy, 'edit')) . "</a>";
    echo join( ', ', $post_terms );
}
else echo '<i>No terms.</i>';

}
[/php]

And that’s it, your custom post types will now display their custom taxonomies and their assigned terms. If you need to add more columns for taxonomies, just add them in the $defaults array in the ilc_cpt_columns function.

22 thoughts on “Add columns for custom taxonomies to custom post types in WordPress”

  1. $terms doesn’t print any value
    I changed manage_event_posts_custom_column to just manage_post_custom_column because all the values on ilc_cpt_custom_column didn’t print anything
    know everything is working but the $terms is not printing anything

  2. Chicharito, please note that this code is for a custom post type so you definitely had to change manage_event_posts_custom_column to manage_post_custom_column & manage_event_posts_columns to manage_posts_columns like you did.

  3. Yes,
    I have a custom type post named “places”
    so I changed manage_event_post_custom_column to manage_places_post_custom_column & manage_event_post_columns to manage_places_post_columns

    The column names are there, but the taxonomies aren’t displayed

    1. Thanks chicharito for your feedback. There was a small bug, change
      [php]
      if( $terms )
      [/php]
      to
      [php]
      if( !empty( $terms ) )
      [/php]
      The code has been updated too. Let me know how it goes.

  4. Elio,

    I’ve been working with this code a little more.

    I’ve noted that if I use manage_post_custom_column instead of manage_myPostType_post_custom_column I can retrieve the values of $post_type, $column_name but not the values of $terms.
    If I use manage_myPostType_post_custom_column I can’t get any of those values.

  5. The correct name of the hook is
    manage_posts_custom_column

    However, as I mentioned above, with the bugfix the code now works. I just missed that one while I was working on other things.

  6. Sorry,

    I misspelled the name of the hook, I’m using the correct one. But I can’t get this to work.
    I’m using WP 3.0.5

  7. your code raises a warning.
    sanitize_term_field() required 5 arguments, so it needs to be changed to:
    sanitize_term_field(‘name’, $term->name, $term->term_id, $taxonomy, ‘display’)

    1. Indeed, Landor, thanks for the heads-up. I’ve updated the code adding ‘edit’ instead of ‘display’ since the context is edit.php. Thanks!

  8. Great tutorial.

    But how can I change the Event Type header so the column is sortable, and also insert the terms into the filter dropdown?

  9. Nice tutorial. I’ve got it working, but I have a customisation question?

    This caters for one custom post type, but I have three (Award, Sponsor and Person). How would I change it so that it detects which post type I’m viewing and adapts the output to suit?

    For example, I have it displaying the terms associated with ‘Award’, but when I go into the Sponsor or Person lists it says ‘no terms’ (obviously because I haven’t told the code about these post types). How can I input the three custom post types into the function?

    Thanks.

  10. Ah sorry, ignore me I worked it out – Just duplicate the $defaults variable:

    `$defaults[‘award_type’] = ‘Award Type’;
    $defaults[‘sponsor_category’] = ‘Sponsor Category’;
    $defaults[‘person_category’] = ‘Person Category’;`

    Of course my other question now is – is there a way to hide the columns depending on which custom post type I’m viewing?

    For example, I only want to see the Award Type column when I’m viewing my Awards custom post type.

  11. Once again I’m going to answer my own question in case it helps someone else out. Here’s what I did:

    function ilc_cpt_columns($defaults) {
    $post_type = get_post_type();
    if ( $post_type == ‘award’ ) {
    $defaults[‘award_type’] = ‘Award Type’;
    } else if ( $post_type == ‘sponsor’ ) {
    $defaults[‘sponsor_category’] = ‘Sponsor Category’;
    } else if ( $post_type == ‘person’ ) {
    $defaults[‘person_category’] = ‘Person Category’;
    } else {}
    return $defaults;
    }

  12. che, que grande!!
    muchas gracias 🙂

    one question, though…
    i found how to make the column sortable, problem is that is not sorting very well 🙁

    add_filter( ‘manage_edit-{$post_type}_sortable_columns’, ‘devpress_movie_sortable_columns’ );

    function devpress_movie_sortable_columns( $columns ) {

    $columns[‘duration’] = ‘duration’;

    return $columns;
    }

    any thoughts?

  13. Hi I cannot get it to print any value The column shows up but that’s it. There are no values entered.

    Is there a problem with WP3.3 for this code?

  14. Same problem as Andrew here. The column is created but neither the taxonomy nor “No content” message is echoed.

    Does this process work with WordPress 3.3? I’m beginning to suspect not.

Leave a Reply to rudolf Cancel reply