Custom taxonomies in WordPress

I’ve spent quite a bit of time over the last week getting to grips with custom taxonomies in WordPress, and I’m really pleased with what I’ve found. A taxonomy is a classification, and WordPress already has two taxonomies buil in: tags and categories. Categories lean towards a more formal taxonomy, which you might setup with forethought and some planning, whereas tags lean more towards a more casual folksonomy, which you might construct “on the wing” in a less formal and more ad hoc style. WordPress uses a generic taxonomy setup to create the tag and category taxonomies, and you can use the same functions to create your own taxonomies.

I’m going to take you through the process of creating a basic taxonomy, creating some terms in it and relating those terms to some posts. There’s some demonstration code in the form of a proof of concept WordPress plugin, which you may find helpful.

A WordPress taxonomy has three parts:

  • The taxonomy itself, in my case that is going to be “sources”
  • The terms within the taxonomy, in the case of tags the terms are tags, in the case of my taxonomy each term would represent a different source
  • The term to object relationships, this is the action of attaching a term to an object; the object may be a post, but it could equally be a page or even a user

To learn more about the data structure of WordPress taxonomies, you can read Ryan Boren’s an introductory post from when the taxonomies were first launched in WordPress.

To create a taxonomy, you need to register it using the register_taxonomy function. As of WordPress 2.7, this creates an array entry in the $wp_taxonomies global array. Registering a taxonomy also sets up a URL query and URL rewrite rules, so you can address the archive pages for your new taxonomy with query URLs (e.g. or rewritten URLs (e.g. The query URLs will work straight away, however to use the rewritten URLs you must run $wp_rewrite->flush_rules(); $wp_rewrite is the section of WordPress which looks at incoming URLs and maps them to various collections of data, e.g. a single post or (in this case) an archive page. Flushing the rewrite rules only needs to be done once, so if your taxonomy is fixed (i.e. not arbitrarily generated by the user) you can register the taxonomy then flush the rules on plugin activation (n.b. you still need to register your taxonomy on every request you want to use it, I tend to do this on the init action hook).

Once your taxonomy is created you can knock yourself out creating terms and associating them with posts (or users, or pages, etc). You use the function wp_set_object_terms, passing it (in my case) the post ID, an array of terms (or the term IDs); WordPress does the rest, creating terms as necessary.

My demo code also includes a quick template tag, similar to the_tags, which you can use to see that the posts have had the appropriate terms related to them. The links for the terms go to the new taxonomy term archives. One thing I have noticed is that if you haven’t set your permalinks up in a format that isn’t basic, then the fancy URLs won’t work (and, of course, you need to have mod_rewrite installed and your .htaccess sorted out correctly, as per the general requirements for fancy urls in WordPress).

There is more you can do with taxonomies and terms, including grouping them and creating hierarchies (as per WordPress categories, where one category can be the “parent” of another), adding descriptions to terms, etc, but these techniques are beyond the scope of this post.

I hope this has been useful to someone, even if that someone is me in six months time when I need these techniques again! Many thanks to Ryan Boren for his patient help while I stumbled through creating custom taxonomies.

Join the Conversation


  1. Hi Simon

    Did you ever find a way of displaying a list of post categories which apply to a particularly taxonomy item.

    eg in a directory where the taxonomies are countries and the categories might be businesses, displaying a list of categories with posts for the taxonomy item “France”?

Leave a comment

Your email address will not be published. Required fields are marked *

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