A Guide to WordPress Custom Taxonomy

Oct 21 2010 by John Gadbois | 54 Comments

A Guide to WordPress Custom Taxonomy

In this guide, we will cover an incredibly great feature of WordPress: Custom taxonomy. Custom WordPress taxonomies give you unprecedented power in the way you can categorize and relate your WordPress content with each other. Though WordPress taxonomies were introduced in WordPress 2.3, it has been revamped in WordPress 3.0 for WordPress developers.

Recently, we had looked at creating custom WordPress post types in the WordPress custom posts guide, and to further our command of WordPress 3.0 site and theme development, we’re going to now discuss custom taxonomies.

What is Taxonomy in WordPress?

Taxonomy is simply a way of organizing data and, in the WordPress world, a taxonomy is a way of organizing and tying your site content together.

Even though you don’t realize it, you’re probably already very familiar with at least one of the built-in WordPress taxonomies: WordPress tags. Tags are a taxonomy because posts can be linked to tags, viewed by tag, and organized by tags. Another WordPress taxonomy are post categories.

Taxonomies add a lot of power to WordPress because they allow users to filter the information they want to see on your site.

A custom taxonomy is exactly what it sounds like — a custom way to relate disparate content together. Custom taxonomies can be applied to custom post types or to regular pages and posts.

Here are some things you might use custom taxonomies for:

  • Release Year for movies
  • Urgency like High Priority, Low Priority for service bulletins
  • Location like room name, zip code or state for events

Each of these taxonomies could help to organize information stored in a WordPress site. If you read the custom post types guide, than the last example (events) on that list will be familiar.

The Game Plan

We’re going to build on the Event custom post type we produced in the WordPress custom post types guide by creating a custom taxonomy for it called Location. The Location taxonomy will allow us to organize our events by their location.

Before we begin, a couple of caveats.

First, for the purposes of this guide, we’ll be using the default TwentyTen theme that comes with WordPress 3 so that we all have the same base theme. However, these instructions can be adapted quite easily for using your own theme.

We’ll also be assuming that you followed along the custom post types guide and that you already have the custom Event post type created.

OK, with that said, let’s get started!

Creating a Custom Taxonomy

As with custom post types, WordPress makes it pretty simple to create your own custom taxonomy.

Let’s take a look at the code required to create the Location custom taxonomy:

add_action( 'init', 'create_locations' );
function create_locations() {
 $labels = array(
    'name' => _x( 'Locations', 'taxonomy general name' ),
    'singular_name' => _x( 'Location', 'taxonomy singular name' ),
    'search_items' =>  __( 'Search Locations' ),
    'all_items' => __( 'All Locations' ),
    'parent_item' => __( 'Parent Location' ),
    'parent_item_colon' => __( 'Parent Location:' ),
    'edit_item' => __( 'Edit Location' ), 
    'update_item' => __( 'Update Location' ),
    'add_new_item' => __( 'Add New Location' ),
    'new_item_name' => __( 'New Location Name' ),
  ); 	
 
  register_taxonomy('location','event',array(
    'hierarchical' => true,
    'labels' => $labels
  ));
}

The above code should go in the functions.php file inside your theme’s directory. The register_taxonomy WordPress function is what actually creates the taxonomy, so let’s start by looking at a couple of the arguments that we passed to it.

'location' is the internal name of our taxonomy.

'event' tells WordPress what post types will use this taxonomy. In our case, we’re tying it to our custom Event post type. You could replace this with 'post' or 'page' if you wanted to use your taxonomy on your posts and pages. You could also pass in multiple post types (via an array) so that multiple types of content can use the taxonomy.

array(...) is the last argument to register_taxonomy. It’s a PHP array of options that tells WordPress how this taxonomy will work.

Let’s go over the keys inside the array argument.

'hierarchical' is a boolean key that states whether or not the taxonomy has a hierarchy, i.e., whether the taxonomy has child categories or not. For our Location taxonomy, we are going to have a hierarchy. For example, think: Building 1, Conference Room A. There may be several Conference Room A’s, but since its parent is Building 1, then we are able to give our location greater specificity.

'labels' is simply information about the way the taxonomy information is going to be printed (as specified by the $labels array inside the create_locations function).

Also notice that the register_taxonomy call is inside a function called create_locations. This is a custom function of ours (it can be named anything you want) that is called when WordPress initializes add_action( 'init', 'create_locations' ).

Still with me? I know it’s a lot, but let’s keep moving forward and soon it will all come together.

Adding Your Custom Taxonomy to Posts

OK, now that we’ve created the Location taxonomy, let’s log into WordPress and create some locations that we can use with our events.

If you look under the Events menu (on the left-hand side of the administration screen), you can see there is a new link called "Locations". Clicking on it will bring you to a screen where you can add, edit, and remove locations from the system.

Adding Your Custom Taxonomy to Posts

Create the following locations:

  1. Building 1
  2. Conference Room A
  3. Conference Room B

Once you do, you should see your new locations in the Location table (right next to the Add Location interface).

Adding Your Custom Taxonomy to Posts

Now that we have some locations, let’s add them to an Event post! Head over the Add New Event screen (or edit an existing event), and you should see a new Locations widget on the right-hand side. This widget appears because when we created the taxonomy, we told WordPress to associate it with the Event custom post type.

Adding Your Custom Taxonomy to Posts

Check off Conference Room A and then publish or save the event. Notice that you can add new locations right from this screen if you find that there’s one missing. This whole display should be familiar to you as it works exactly like WordPress post categories. If you make a non-hierarchical taxonomy, then it will behave exactly like post tags.

Now that we’ve created some locations and used one of them to an Event post, we want to display each event’s location on the front-end of the site so that our readers can see them. Let’s do that next.

Displaying Your Taxonomy Information

The first place we want to show the location is when we are displaying a single event.

If you remember back in the previous custom post types guide, we created a file called single-event.php in our theme directory that was used to display an individual event. If you were doing a custom taxonomy on a default content type (i.e. posts or pages), then you can do the same thing, but only you’d need to do it in single.php.

When we visited an event, it looked like this:

Displaying Your Taxonomy Information

We can add the location (or locations) to the post using WordPress’s get_the_term_list function, which looks like this:

get_the_term_list( $id, $taxonomy, $before, $sep, $after )

Here are brief descriptions of each get_the_term_list argument:

  1. $id – the ID of the event to get the taxonomy for
  2. $taxonomy – what taxonomy to get ('tag', 'location', etc.)
  3. $before – The HTML to print before the list
  4. $sep – what should separate the various items in the list
  5. $after – The HTML to print after the list

We can use the get_the_term_list function to display all locations assigned to an event using the following code block:

<?php echo get_the_term_list( get_the_ID(), 'location', "Location: " ) ?>

This tells WordPress to print the current Event’s ID (get_the_ID()), use our Location taxonomy, and prepend the list with the text, "Location: ".

We won’t worry about specifying a separator since the default (which is a comma) will work just fine. You could use another separator if you want, like – or |.

One other thing to note is that each displayed location will automatically be a link to a page that shows all posts that have the same location. (We’ll talk about how to customize that page in a bit).

To add the location’s list to our single-event.php file, replace the following section:

<div class="entry-meta">
<?php twentyten_posted_on(); ?>
</div><!-- .entry-meta -->
</pre>

With:

<div class="entry-meta">
<?php twentyten_posted_on(); ?>
</div><!-- .entry-meta -->
<div class="entry-meta">
<?php echo get_the_term_list( get_the_ID(), 'location', "Location: " ) ?>
</div><!-- .entry-meta -->

Now if we refresh the event’s page in our browser, we can now see the location assigned to it:

Filtering Posts by Custom Taxonomy

Filtering Posts by Custom Taxonomy

Now that we’re displaying our Location taxonomy in our events pages, we need to configure a page template to show all the events for a given location.

As noted previously, the "Conference Room A" link will automatically take you to a page that displays all the posts with the given location (which is pretty useful for when you want to know what other events will be happening in "Conference Room A").

But since we’re tying our taxonomy to a custom event type, we’ll need to get our hands a little dirty and make some modifications.

If we follow the link as-is, we’ll see the following:

Filtering Posts by Custom Taxonomy

To understand what’s going on, we need to know a little about WordPress’s template hierarchy. Whenever a page is loaded in WordPress, it looks in your theme for the correct template to load based on a specified naming convention. When a taxonomy page is encountered by the user, the sequence in which WordPress checks what WordPress theme page template to use is this: taxonomy-[your_taxonomy_term].php > taxonomy-taxonomy.php > taxonomy.php > archive.php > index.php.

What this means is that, going left to right, WordPress will use the first file it encounters that matches the naming convention. In the TwentyTen WordPress theme, the first file that is a match is archive.php since the first three files are non-existent. That explains why we saw the "Blog Archives" heading in the page.

To display our locations, we’re going to add a file called taxonomy-location.php.

Since this is higher in the page template hierarchy (i.e., it’s taxonomy-[taxonomy-term].php from above), WordPress will load this file instead of archive.php when a user hits the location taxonomy page.

So to get started, create taxonomy-location.php in your theme’s directory and copy the contents of tag.php into it so that we have a starting point.

The first thing we need to do is get the location that we are currently viewing (like "Conference Room A").

WordPress terminology calls this the term of the current custom taxonomy. To get the terms of an event post, add the following line right below the get_header() line.

<?php $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); ?>

All of the term information (ID, name, etc.) is stored in the $term variable, so we can now output it wherever we want.

We are going to display the term at the top of the page, so let’s replace the tag heading with our own heading for location.

So go ahead and change this code block:

<h1 class="page-title"><?php
printf( __( 'Tag Archives: %s', 'twentyten' ), '<span>' . single_tag_title( '', false ) . '</span>' );
?></h1>

To:

<h1 class="page-title"><?php
printf( __( 'Events in Location: %s', 'twentyten' ), '<span>' . $term->name . '</span>' );
?></h1>

Now if we click on the "Conference Room A" link from our event, we can now see what location we are looking at. But there are still no events showing.

To fix that, we need to modify the default WordPress loop to manually find Events, and not just Posts.

Right below the line you added, add the following line so that we can make a custom WordPress query:

 <?php query_posts(array( 'post_type'=>'event', 'location'=>$term->slug)); ?>

query_posts will override the default WordPress loop and replace it with a custom one that finds all Events with the current location.

Due to a bug in WordPress (at the moment), any other post types that are at the current location will also be returned. This is not a problem for us right now, but is something to keep in mind in the future as you work with custom taxonomies.

Once we’ve added the query_post call, here’s what we see:

As you can see, we’re now showing all of our "Conference Room A" events (we only have one), awesome!

If you noticed, when originally creating the locations, you can optionally specify a location description. How would we add that to our template? That’s pretty easy. Just add the following line right under the closing h1 tag in taxonomy-location.php.

 <strong>Description:</strong><?php echo term_description( '', get_query_var( 'taxonomy' ) ); ?>

Now our page will look like this:

And that’s it! We are now showing our custom taxonomy on individual Event pages and we can also list all events in a given location.

Summary

I hope that after reading this guide, you now have a good idea on how to set up your own custom WordPress taxonomies. This is what we did:

  1. Create a custom taxonomy (the Location taxonomy)
  2. Add the Location taxonomy to posts (in this case, in the Event custom post type)
  3. Display the custom taxonomy in posts
  4. Filter and display posts by their custom taxonomy
  5. Create a page template for our custom taxonomy

With the inclusion of custom post types and the improvement of custom taxonomies in WordPress 3, the sky is really the limit in content creation.

How are you going to use this new functionality?

Related Content

About the Author

John Gadbois is a 27-year-old web developer who codes and runs Domain Superstar, a domain name tools site. He also works on the online calculator site, CalculatorPro.com and enjoys working with WordPress, PHP, jQuery, and Ruby on Rails.

54 Comments

Shain

October 21st, 2010

Thank your for this very usefull guide !

Do you know if there is a way to add custom field to a taxonomy ? For example, to store more information about the location (a picture or something else).

Barry Roodt

October 21st, 2010

Good guide.

Just noticed a typo which may cause confusion: At one point you refer to taxonomy-locations.php instead of the singular taxonomy-location.php

Chief Alchemist

October 21st, 2010

Nice work John. Thanks. Mind if I add a few things?

- Maybe it was just me but I found WP’s support for taxonomies a bit overstated. Mainly the built in functions seem to be pretty limited in capabilities and parameters. To get what I needed I had to do some homegrown hacking.

- The biz need I had to satisfy was closer to uber-tags than taxonomy buckets. From this project I developed a couple custom functions that make it easier to work with taxonomies. I don’t mean to link-drop but for anyone who might be interested I’ve shared those functions at:

http://www.chiefalchemist.com/customize-wordpress-taxonomy-functions-the-remix/

In fact, this site is the site I used the taxonomies on. Yes, it’s “ambitious” if not daring in it’s approach. It would have been impossible without taxonomies.

Finally, FWIW, I also used Yoast’s taxonomies plug-in (but did have some issues with it, which are also documented somewhere on my site.)

Cheers!

krike

October 21st, 2010

very nice :D bookmarked for later reading :)

Ahmad

October 21st, 2010

Wow very nice i always wonder what is this for now i get it heheh thanks for the info Really helped me

Jacob Gube

October 21st, 2010

@Barry Roodt: You’r a rockstar, thanks. It’s been corrected. And just for people that are curious, it matters because we register the taxonomy as “location”.

John G

October 21st, 2010

Excellent post. I wish I would have known more about this earlier, I could have really used it to organize my site. It might be a lot of work to go back and do it now but on all my upcoming sites I’m going to make use of this technique. Thanks!

Spence

October 21st, 2010

Cheers for this, i’m more of a designer than a programmer and still managed to follow it!

dan

October 21st, 2010

good stuff! seems recent articles about new wordpress features are extremely helpful. thanks a lot, looking forward to the next one.
cheers

Mikhail

October 21st, 2010

Great writeup. This is how you wright. simple and in depth. I wish my preprocessors have read this blog. I would not have to dig through so much bad wordpress hacking. Bookmarked.

Pierre

October 21st, 2010

Your WordPress tutorials are always extremely useful and interesting to read. Thanks for this one, it’s (another) great option I didn’t know about WordPress.

TNk

October 21st, 2010

Great WP articles John ty!

Jacob Gube

October 21st, 2010

@Pierre: 100% agree with you on that. They’ve inspired me into creating a sophisticated WordPress theme as a side project for myself (that when finished, I will release to the public free of charge).

j08691

October 22nd, 2010

Good article, thanks.

Jocke

October 22nd, 2010

This was exactly what I needed! This article was way better than the information in the codex. Keep up the good work!

Thomas Herold

October 22nd, 2010

I am wondering if that could be used to create a glossary? I looked at plugins, but could not find anything good.

Ayman Aboulnasr

October 23rd, 2010

Thank alot for this in-depth article on custom taxonomies.
just in time for a project i’m working on!

Melanie

October 25th, 2010

Wow, this is cool! Nice to know for next time I build a WordPress site for a client. I have a feeling the ease/capability of WP would be all the more impressive, knowing this now.

John

October 25th, 2010

@Thomas

It could potentially be used for a glossary, but I think you’d have to manually assign the glossary terms for each post. Then you could have a page that listed all your glossary terms and the posts that were tied to that term.

Elaine

October 26th, 2010

Wish I found this a few days ago.. would have helped me so much when I was still learning! Great resource :)

nomadone

October 27th, 2010

Thanks for this detailed explanation, it cleared up a few issues with regard to what each variable means.

Any chance you can post the entire code which displays posts from a specific term within a specific taxonomy, or even better, one which can be reused for any term in any taxonomy?

I’ve been fiddling around with something that looks like this but can’t seem to figure the term variable thing out? Don’t laugh, I’m a designer :)

slug;

$args = array(
‘post_type’ => ‘audio’,
‘taxonomy’ => ‘Audio Category’,
‘term’ => $term
);

// assigning variables to the loop
global $wp_query;
$wp_query = new WP_Query($args);

// starting loop posting only
while ($wp_query->have_posts()) : $wp_query->the_post();
?>

Chaz Chumley

October 28th, 2010

I am following your article here and keep running into the same issue. I can create a custom taxonomy with no issue, I can display the taxonomy on the post with no issue. However when I click on the taxonomy I get a 404 page. Regardless if I create a taxonomy.php page.

My custom taxonomy is Products with a term of Photoshop. I have tired creating a taxonomy-products.php and taxonomy-products-photoshop.php page and I still always get a 404 page. The url looks like http://communite/products/photoshop Any suggestions???

Jacqueline

October 29th, 2010

Thanks for this article! I’ve been thinking about custom taxonomies for WP as of late, and this came at the right time. :)

Tim

November 14th, 2010

Great article – just what I was looking for!

I have run into one issue with custom taxonomies though and that is pagination. I can set the number of posts to display when listing objects of a custom taxonomy, but going to page 2 of the results always gives a 404.

Any thoughts would be appreciated.

Thanks

ezhil

November 16th, 2010

hello
iam using custom taxonomies in my site,so i did have seperate templates for displaying them.
i have created a taxonomy called people and a term called star and also respective template to star (taxonomy-people-star.php) every thing works fine http://sportsstatus.in/dev/people/star/ .
but when i query some other taxonomy like http://sportsstatus.in/dev/people/star/?sports=tennis to it the template structure changes to the archive format. how to over this.
i want the original template structure assigned for star(taxonomy-people-star.php) to work.

Trangsene

November 17th, 2010

Hello,

Great article. I’ve added a custom taxonomy to my project and it works well but I have a problem. As soon as I activate permalinks, the links created with this code /location/name_of_the_location/ :
echo get_the_term_list( get_the_ID(), ‘location’, “Location: ” )
aren’t working anymore.

Any idea ? I’m desperate :-(((

Trangsene

November 17th, 2010

I’ve lost hours on this and the solution was really simple : I found it here : http://seanbehan.com/programming/how-to-flush-your-permalink-structure-in-wordpress-when-using-taxonomies-or-wordpress-taxonomies-not-working-instead-i-see-a-404-page/

I had to modify my permalinks structure, record it twice in the admin and then it works !

Terry

December 6th, 2010

I used this guide to build my custom taxonomies and everything seems to work great except one thing. This may be something to do with the template I am using, but I am clueless at this point.

I copied the code from my archive.php file and pasted it into a new file called taxonomy.php, which builds an archive of posts from the taxonomies I have defined. I added a post-thumbnail and prettier formatting that my standard archive.php file. My problem is, that I cannot change the length of the_excerpt that it displays on the taxonomy.php page. I have tried adding custom functions to my functions.php file to control it and almost every plugin available and nothing will change it. I need it trimmed on my taxonomy archive page, but display a full excerpt on the single post page.

I have to get it to work as described above. I can’t paste the full text into the_content, because it totally ruins my formatting.

Shane

January 7th, 2011

Hi

Great tutorials.
I’ve created several content types but I’m come across a problem. I have a hierarchal custom taxonomy which I called “country” and then using this assign my posts related to whatever country name they are associated with.

In my case I would be using the same taxonomy for multiple content types. Now when I call up an archive page or single for a custom post type and use e.g. get_the_term_list it will show the country name, but when clicking on it, it shows posts of other content types as well (that have the associated taxonomy).

How do I limit the taxonomy to that particular content type for users when browsing but still have the flexibility to use it across content types when posting content?

Barry

January 9th, 2011

Hello,

Thanks for this tut, best overview I’ve seen so far.

You mentioned a WordPress bug at the very end of your article. Just wondering if it’s what is affecting my simple taxonomy search menu.

I registered two taxonomies to work with ordinary posts. I can assign them correctly in the combo box. I’m using a taxonomy search widget, which is generating a good URL. In my results page I get every post, as opposed to just the posts tagged with the taxonomy value in question.

Ecy Anboo

January 13th, 2011

What a good article.
I’ve been waited for it fo a long time.
I wondered that customizing wordpress would be easier.

nick

January 27th, 2011

Thanks for explaining that. My question is about showing multiple taxonomies in a post, but only the taxonomies that have a value.

For example, on a portfolio site, if there are taxonomies for “Writer” “Illustrator” “Designer”, I want to return only the taxonomies that I have given values to. I could hard code a line of code for each taxonomy, but I do not want any blank fields returned.

Do you have any advice?

m00dles

February 17th, 2011

Wonderful writeup, I’ve struggled with WP taxonomies since I first heard of them. This was conceptual and practical, and will help me with my church’s site organization tremendously. Thank you.

helenP

April 12th, 2011

Thsi has been areally useful resouirce thank you
Is there a way to show all the events in building one?
i.e. show events for all the chidl catgeories of teaxonony building one

David

April 15th, 2011

Great post,
what if I want the taxonomy not to be hierarchical but to display in the Post Edit Screen with checkboxes (like a category)?

Thao

May 6th, 2011

@Chaz Chumley

You just need to do a “functions flush”. Go to WP Admin > Settings > Permalinks and simply click “Save changes”. You don;t need to change anything; it just flushes the system. Your taxonomies will appear like magic.

Vern

May 10th, 2011

Holy Cow!

I can NOT get any posts to show on the taxonomy page. I don’t know what’s going on. I think everything is the same, so there must be something else happening…

Anyone know what could prevent the posts from showing?

Amy

May 15th, 2011

Great post!! Just what I was after and very easy to follow. Thanks very much! :-)

Powderflask

June 2nd, 2011

A great tutorial – many thanks.

Sue

June 13th, 2011

Aha, tag.php! Thank you – I could NOT for the life of me find where to change “Tag Archives” as a title :-) (using a child theme of Twentyten that didn’t have that. duh!)

Raffo

June 18th, 2011

Excellent job, Thanks.

One Million Monkeys

June 23rd, 2011

Thanks for an incredible useful tutorial.
I’ve tried to wrap my head around custom taxonomies and this guide has been the revelation for me.
One small suggestion, maybe make it even clearer that you need the code from the “WordPress custom post types guide” – although it just might be me who is a bit slow :)

WPExplorer

July 2nd, 2011

Wow. this is the most thorough guide to WP taxonomies I have seeing by far. I was looking for a way to show the categories of my taxonomy and this post helped me a lot, thanks!

shujah

July 25th, 2011

Thank your for this very usefull advice:)

Alex

August 8th, 2011

perfect, really helped me out. thx for this great article!

eric

August 24th, 2011

trying to get this to work on another custom template that i downloaded and can’t get it to drill down and some other display things that i can’t seem to figure out how to fix. would anyone be able to help me out ???

eric [at] webalterations [dot] com

Patricia

September 16th, 2011

Is there any way to create a page where all the taxonomies are listed? If I , for example, have 5 different taxonomies. Actors, Genre, Atmosphere etc. and I’d like to have some pages where my readers can chose a term, eg. ChickFlick or something like that?

Because I’m lazy enough to admit that I don’t want to add all the terms manually.

Thanks in advance

Mark

September 22nd, 2011

Very helpful. I guess one key difference between taxonomies and categories is that a post can quite reasonably have multiple categories, whereas it’s best than a post just has one place in your taxonomy.

Johnny

September 29th, 2011

Excellent article.

I was trying to build a Yellow Page function and didn’t really get it right using custom post types only. I found your article about custom post types and found out that I actually did the right thing, but adding the taxonomi function right got me through.

So now I just need to add a function to show the taxonomy tree on the taxonomy page as well to get all the way.

John joyce

September 30th, 2011

You Give Very Useful Information Its Really Nice. Keep It Up.

logesh

November 2nd, 2011

How to set a default taxonomy term

kea

October 7th, 2012

this is work for permalinks?

Ændrew

October 10th, 2012

Thank you for posting this, I always get stuck on the “Making stuff show up in the taxonomy listing pages” part of it. It really is stupid that WordPress can’t ascertain by itself what taxonomy is being requested — if the template hint being given is taxonomy-custom_taxonomy.php, it already knows the taxonomy being requested is called “custom_taxonomy” because it just loaded the file. Why one must override the loop in these situation dumbfounds me.

Lore

May 31st, 2013

Hi Six Revisions,

I was wondering, what if I want to make a page for a term in my taxonomy, ie, describing “conference room A” features. Is there a method for this?

Have 100 taxonomy terms that need to show the custom fields placed into taxonomy term.

Thanks.

Leave a Comment

Subscribe to the comments on this article.