How to use custom taxonomies in WordPress

In this article, I will cover custom taxonomies and how they are created. I will make three custom taxonomies to show how the code can be reused with ease and also adapted to the needs of each taxonomy. Let’s start with a definition of custom taxonomies.

What are custom taxonomies ?

Taxonomies are different ways of grouping things together. A real life example might be TV shows: they can distributed by a number of different variables, like the channel airing them, their genre, or even the hour they air in.

In WordPress, taxonomies are grouping mechanisms that separate your posts. By creating custom taxonomies, you are creating ways to divide them as you wish; because by default you can only divide your posts/custom post types by tags or categories.

Custom taxonomies give you even more flexibility when defining your WordPress site’s behavior.

Creating our custom taxonomies

As I said before, we will create three taxonomies: one of them will be hierarchical like categories, and the other two will behave like tags, which have no hierarchy. We will start with the “Genre” taxonomy. This will be the hierarchical one because inside some genres, I will want to have sub-genres.

The genre taxonomy

This article will follow the same process as the custom post type article: I will give you the code first and then I will go through it line by line. The code for this hierarchical taxonomy is:

add_action( 'init', 'register_genres' );

function register_genres() {

    $labels = array( 
        'name' => _x( 'Genres', 'genres' ),
        'singular_name' => _x( 'Genre', 'genres' ),
        'search_items' => ( 'Search Genres' ),
        'popular_items' => ( 'Popular Genres' ),
        'all_items' => ( 'All Genres' ),
        'parent_item' => ( 'Parent Genre' ),
        'parent_item_colon' => ( 'Parent Genre:' ),
        'edit_item' => ( 'Edit Genre' ),
        'update_item' => ( 'Update Genre' ),
        'edit_item' => ( 'Edit Genre' ),
        'update_item' => ( 'Update Genre' ),
        'add_new_item' => ( 'Add New Genre' ),
        'new_item_name' => ( 'New Genre' ),
        'choose_from_most_used' => ( 'Choose from the most used genres' ),
        'menu_name' => ( 'Genres' ),
    );

    $args = array( 
        'labels' => $labels,
        'public' => true,
        'show_in_nav_menus' => true,
        'show_ui' => true,
        'show_tagcloud' => true,
        'show_admin_column' => false,
        'hierarchical' => true,
        'rewrite' => true,
        'query_var' => true
    );

    register_taxonomy( 'genres', array('movies'), $args );
}

We start with the same first line in this post as we did in the custom post type article; and in this line all we do is hook our function to WordPress init so that it fires when WordPress fires:

add_action( 'init', 'register_genres' );

Now, just like in the creation of custom post types, we need to create a labels variable and start by placing the plural and singular names of our taxonomy, like so:

function register_genres() {
    $labels = array( 
        'name' => _x( 'Genres', 'genres' ),
        'singular_name' => _x( 'Genre', 'genres' ),

With these two labels out of the way, we now move on to the text displayed when we want to search inside the Genres taxonomy:

'search_items' => ( 'Search Genres' ),
'popular_items' => ( 'Popular Genres' ),
'all_items' => ( 'All Genres' ),

The next two labels are exclusive to hierarchical taxonomies. This is where we set the text for the “Parent Genre”. We also need to add this text with a colon after it in the next line, because WordPress will use both these strings in the administration area:

'parent_item' => ( 'Parent Genre' ),
'parent_item_colon' => ( 'Parent Genre:' ),

In the next two lines we create the labels for editing a taxonomy, the “Edit Genre” label and the “Update Genre” label:

'edit_item' => ( 'Edit Genre' ),
'update_item' => ( 'Update Genre' ),

Now we edit the labels necessary for the creation of new Genres, the “Add New Genre” label and the new item label:

'add_new_item' => ( 'Add New Genre' ),
'new_item_name' => ( 'New Genre' ),

The last line is where we set the name that will appear on the menu:

   'menu_name' => ( 'Genres' ),
 );

This is all for the labels in hierarchical categories. We now move on to its arguments, and like in movie post type example, I will create an args variable that will hold all of the arguments.

The first thing we need to add is the labels so we will just point to the labels variable:

$args = array( 
   'labels' => $labels,

In the next three lines we take care of the visibility of this taxonomy. All this code does is make the taxonomy visible in the admin interface:

'public' => true,
'show_in_nav_menus' => true,
'show_ui' => true,

In the next line we decide if we want the the tag cloud widget to use this taxonomy, and then we decide if we want to allow automatic creation of taxonomy columns on the post types it’s associated with. We set both of these option set to “true”:

'show_tagcloud' => true,
'show_admin_column' => true,

In the last three lines we first decide if our taxonomy will be hierarchical or not, then we set the rewrite method. Remember, making it hierarchical makes it behave like WordPress categories. Setting the rewrite variable to true means that each Genre’s name will also be its slug in the URL. Lastly, setting query_var to true allows us to query this taxonomy by it’s name in our PHP.

   'hierarchical' => true,
   'rewrite' => true,
   'query_var' => true
);

All we need to finish the creation of this custom taxonomy is the register_taxonomy function; and this function takes three parameters. The first one is the name of our taxonomy (no capital letters or spaces), the second one defines to which post types it will be attached, and finally we need to place the arguments variable.

   register_taxonomy( 'genres', array('movies'), $args );
}

Our first taxonomy is done. Now, we will create the two non-hierarchical (tag-like) taxonomies.

The actors and year taxonomies

Because these two taxonomies do not behave like the first, we’ll be giving them some different labels. Again, I’ll show you the code first; and then we’ll go through it all line-by-line.

add_action( 'init', 'register_actors' );

function registery_actors() {

    $labels = array( 
        'name' => _x( 'Actors', 'actors' ),
        'singular_name' => _x( 'Actor', 'actors' ),
        'search_items' => ( 'Search Actors' ),
        'popular_items' => ( 'Popular Actors' ),
        'all_items' => ( 'All Actors' ),
        'edit_item' => ( 'Edit Actor' ),
        'update_item' => ( 'Update Actor' ),
        'add_new_item' => ( 'Add New Actor' ),
        'new_item_name' => ( 'New Actor' ),
        'separate_items_with_commas' => ( 'Separate Actors with commas' ),
        'add_or_remove_items' => ( 'Add or remove Actors' ),
        'choose_from_most_used' => ( 'Choose from most used Actors' ),
        'menu_name' => ( 'Actors', 'actors' ),
    );

    $args = array( 
        'labels' => $labels,
        'public' => true,
        'show_in_nav_menus' => true,
        'show_ui' => true,
        'show_tagcloud' => true,
        'show_admin_column' => true,
        'hierarchical' => false,
        'rewrite' => true,
        'query_var' => true
    );

    register_taxonomy( 'actors', array('movies'), $args );
}

As you can see, the code for non-hierarchical taxonomies is pretty much the same . The arguments are all the same and in the labels all we did was remove the parent_item and parent_item_colon, because these two were restricted to hierarchical taxonomies. Then we added three more lines that are restricted to non-hierarchical taxonomies and I will go through these three now.

The first line we added was the separate_items_with_commas variable; and in here we add the text we want to appear where normally we have “Separate tags with commas”:

'separate_items_with_commas' => ( 'Separate Actors with commas' ),

The next line we added was the add_or_remove_items variable; and this is the text that appears in the metabox when Javascript is disabled in the user’s computer, this more of a backup to be used in themes that are meant for sale:

'add_or_remove_items' => ( 'Add or remove Actors' ),

And the last line we added was choose_from_most_used and this one defines the text that appears in the metabox below separate tags with commas :

'choose_from_most_used' => ( 'Choose from most used Actors' ),

This are the only changes to be made when switching from hierarchical to non-hierarchical taxonomies. To adapt this to the Year taxonomy all you need to do is copy the code and change its labels (assuming you want the arguments to stay the same). As you can see, reusing this code is simple and practical.

Show your custom taxonomies on the front end

The code for retrieving this information is actually very small, and the function takes four parameters. In the first one we need to place the post ID, in the second one we will place the taxonomy we want to present, the third one is the text we want to show before they are presented, then we have to set the string that will separate the taxonomies, and finally we set the text that will appear after each one:

$actors = get_the_term_list( $post->ID, 'actors', 'Actors in this Movie: ', ', ','' );

Now all you need to do is echo this variable and the actors that are associated with that particular movie will appear.

Final thoughts

Custom taxonomies are a useful add on when you are creating a custom WordPress site that’s more than a blog. When combining custom taxonomies and custom post types just right, you can create any kind of website using WordPress. Now go on and test your own combinations!

Sara Vieira is a freelance Web Designer and Developer with a passion for HTML5/CSS3 and jQuery. You can follow her on twitter or check out her website. More articles by Sara Vieira
  • This is great share Sara. Totally taken point. Custom taxonomies are very beneficial and help in creating any king of WordPress website. I have tested the same and dint faced any problem
    http://www.wdipl.com/

Home CSS Deals HTML HTML5 Java JavaScript jQuery Miscellaneous Mobile MySQL News PHP Resources Security Snippet Tools Tutorial Web Development Web Services WordPress