Background
WordPress lets you categorise your posts according to “tag”, and “category”. Which is fine. However, for some time now WordPress has supported a concept called “Custom Taxonomies”. Which is a long winded way of saying “We’ll let you choose how your organise and present your posts – however you want”.
This isn’t something I’ve ever felt the need to use before (I’m happy enough with tags on this blog) – however having used them recently I’ve really begun to appreciate how powerful they are – and I’m amazed that more people don’t use them to create a more sensible structure to their WordPress sites.
That said, I’m a bit of a geek, who’s not averse to diving into code, and isn’t intimidated by a set of cryptic API documentation 🙂
The Business Case
So, what can taxonomies do for you?
The site I built this for is a resource all about baby slings, the different types, the different brands, and people’s experiences, of finding, choosing, and using them.
Tagging just seemed to create a big, hard-to-navigate tag cloud that didn’t create an easy way for people to find the right content on the site that was going to be useful to them (Feedback has suggested that people are either looking for information about a particular brand, or a specific type of sling irrespective of brand).
The How-To
So, out went the “tags” (We removed them from most old posts, don’t add them to new posts, and got rid of the “tag-cloud”). Next step was to install Joost de Valk’s Simple Taxonomies plugin. This is one of Joost’s simpler plugins. In general all it does is let you create a taxonomy, and manage the terms within that taxonomy.
Actually, as an aside – I suspect this is why custom taxonomies haven’t really taken off. Out-of-the-box you have to create code to set them up and use them for effective site navigation. If the functionality provided by Joost’s plugin was in WordPress core, and theme authors really started coding for this stuff, I’m sure it would fly, but I digress …
So, using the plugin, we created two taxonomies – “Brands”, and “Sling Types”.
Next step was to go back through our posts (Fortunately this was in the early days of the site!), and correctly “tag” the posts against the right taxonomies. So on the SnugBaby review, we set the “Brands” to “SnugBaby”, and the “Sling Types” to “Mei Tai”.
Now we’ve got all of our posts beautifully organised, but we don’t have a way to view them. Before we get to that though, there’s just one more step. For every “term” (ie, for every brand, or sling type) we need to provide a description. Your new taxonomies can be found in the “Posts” section of the WordPress backend, simply click on the taxonomy, e.g. “Brands”, then work your way down the list adding a useful description.
Now we can actually start presenting this information sensibly!
Theme Work
Now, we’re going to use that list of “terms”, and their descriptions, to create a top-level list of “brands”. Download the file below, and save it in your WordPress theme directory. We called it “brand-directory.php”, but the name doesn’t really matter.
This will create a new page template called “Brand Directory” (If you want to change the name, edit the comment at the top of the file). Now create a page in WordPress, provide some content that you’d like to use as an introduction, and set the page template to this new file:
Basically all this file does is display the page content you created:
<?php the_content(); ?></p>
followed by each one of the terms that you’ve used, along with it’s description:
$terms = get_terms(‘brands’);
foreach ($terms as $term) {
echo $term->description;
and a link to all of the posts that have been assigned to that term:
$wpq = array (‘taxonomy’=>’brands’, ‘term’=>$term->slug);
$query = new WP_Query ($wpq);
$article_count = $query->post_count;if ($article_count) {
echo “<a class=\”taxonomy-rel-link clearfix\” href=\”/brands/”.$term->slug.”\”>”.$article_count;
} else {
echo “<span class=\”taxonomy-rel-link\”>$article_count”;
}echo ” related article”;
if ($article_count!= 1) echo “s”; else echo “”;
if ($article_count>0) {
echo ” – click to view</a>”;
} else {
echo “</span>”;
}
echo “<br />”;;
And there you have it, a dynamic data driven directory that keeps itself up to date whenever you “tag” a brand – all you have to do is add a description for the brand!
For an example see the “Get Your Hands Back!” brand directory here.
Pingback: Using Wordpress taxonomies to create a product directory | bllogger
Pingback: Custom Taxonomies In Wordpress Plugins – Lee Willis’ Blog | leewillis.co.uk
September 8, 2009 at 3:03 am
This is helpful! I had a question and thought you might be able to answer it. This code worked – but I wanted it to do something a little different on my site. Is there a way to change the php file so that, instead of just showing a link (with a number) that a user can click to go to the posts, it actually lists out the titles of the posts under each listed item, sorted by date with the date in parentheses? Like this:
Brand 1
Post 1 (Date)
Post 2 (Date)
Brand 2
Post 1 (Date)
Post 2 (Date)
Thanks!
September 8, 2009 at 9:21 am
Hi Sven,
Yes, you can fairly easily do that, just rip out the following chunk of code in the brand-directory.php file:
if ($article_count) {
echo “slug.”\”>”.$article_count;
} else {
echo “$article_count”;
}
echo ” related article”;
if ($article_count!= 1) echo “s”; else echo “”;
if ($article_count>0) {
echo ” – click to view”;
} else {
echo “”;
}
At this point in the code, $query->posts should contain all of the matching posts so you should just be able to cycle through them and output whatever you want. Have a go – and if you get stuck let me know and I’ll whip up a quick sample!
February 1, 2010 at 6:58 pm
What if you had multiple levels that you wanted to group by.
So you had carriers, and under that you had left shoulder carriers and right shoulder carriers.
Would you create multiple pages to create the category structure?
February 2, 2010 at 8:44 pm
Hi Michael, thanks for the comment. In all honesty this approach isn’t really meant for hierarchical data (Although you could do that if you wanted) – if I was doing subcategories then I’d just use categories – or set the taxonomy to be hierarchical.
Hope that helps.
February 2, 2010 at 9:41 pm
Hey Lee, After banging my head on the keyboard for a few hours last night, I finally figured out what you already knew. I’m hoping that WP 3.0 will incorporate hierarchical tags more easily, because then directories should be much easier.
April 1, 2010 at 5:21 pm
Great article. I’m wondering if this custom taxonomy stuff can be used to set up a decent structure for a music site, where each post is the song (video), then the following taxonomies:
1) Artist
2) Genre
3) (Record) Label
4) Album
Sounds roughly ok, but just a couple of obvious thoughts…
a) You could tag each song (post) as belonging to a particular artist, and also an album, but that seems redundant. In reality, the album should be “owned” by the artist. So a post should just need the album name, and the artist could then be retrieved from the album?
b) Similarly, each artist (let’s say for sake of argument) only has one record label. Seems redundant again to tag each track with a record label. It should be the artist or perhaps album name that is tagged with the label.
Are these structures possible with custom WP taxonomies? Or is just a case of attaching all the tags to the posts and accepting some duplication?
Any insight would be welcome …..
thanks,
lee
April 5, 2010 at 8:29 am
Yes – although in reality a lot of albums (Think compilation albums) break this model, e.g. an album can contain lots of different artists. I think you probably realised that though!.
I think what you’re trying to create is something like this:
http://www.getyourhandsback.co.uk/sling-shops/
This is a taxonomy archive page, so for example b2boutique is a term within the “vendors” taxonomy. We then list the relevant terms within other taxonomies that make sense for this vendor.
If you had a post per song (For example), then you would have to tag it with the artist, genre, label, and album. Then you could build (For example) an “artist directory”. For each artist you could then query the posts with that artist, to find out what albums, labels and genres you should list to enable the user to “drill-down” to the next level.
The site I linked to above has to manually link vendors to sling types – since posts are tagged with multiple different vendors, sling-types and brands.
In your case if you make your posts at the lowest level – e.g. “Song” then you should be able to dynamically generate this stuff, e.g. in an artist directory you might do:
Identify all posts with that artist
– For each post identify all albums, labels and genres that are tagged
– Merge this list
– Present them as links for the user to drill through, e.g. to the “Album” archive
[Note: While the WordPress API does give you all the functions you need to do this – it’s probably a lot more efficient to write a bit of SQL to query the relevant tables directly]
I think “artist”, “label” and “genre” archives would work like this, and not show a list of posts. The “album” archive would probably be the only one that displayed a list of “posts” with this tag so that you can get to the actual song posts.
, to find out what albums, labels and genres you should list to enable the user to “drill-down” to the next level.
Hope that helps.
April 5, 2010 at 3:07 pm
Yep. That’s exactly the sort of approach I eventually realized would be needed. Each post is a song, and then just tag everything from there, and do the work in the queries …. thanks for the reply!!
April 18, 2010 at 5:55 am
Hi, Nice write up and solution! Glad to see that there are others that are using Taxonomies to organize their websites. One of my plugins might be of use to you and your readers. It allows you to associate an image from your Media Library to any term of any Taxonomy. It also comes with a shortcode so users don’t have to modify their themes to use it. It is free and GPL and can be found here:
http://wordpress.mfields.org/plugins/taxonomy-images/
April 18, 2010 at 8:33 am
Nice plugin, and thanks for the comments Michael.
May 24, 2010 at 9:43 pm
Is there anyway to either:
(1) add categories (and permalink %category% usage) for custom post types
(2) or have taxonomy terms in the post permalink?
Have a Gallery post type (slug gallery)
Have a category or taxonomy as Landscapes (slug landscapes)
desired outcome: example.com/gallery/landscapes/postname
May 25, 2010 at 7:24 am
Not that I’m aware of – at least the permalinks only suggests that you can do this with %category% and %tag%, not %term% which is what I’d expect.
http://codex.wordpress.org/Using_Permalinks
June 20, 2010 at 4:53 pm
Does this plugin work on WordPress newest version 3.0?
June 20, 2010 at 8:31 pm
That’s a good question. The blog that this article was written about is still on 2.9, but I’m intending upgrading it over the next few days – I’ll report back and let you know!
June 29, 2010 at 11:08 am
Can this be done without a page template? I want to create a theme that has this directory out-of-the-box and I don’t want to tell my client that he has to have a page based on that template or else! :p
Basically, make it idiot-proof.
June 29, 2010 at 8:04 pm
I imagine you probably could. You could make the theme file include a specific template to do the functions if it encountered a certain URL or similar, or maybe use rewrite rules or similar – sorry I can’t help more with the exact solution but that might set you off in the right direction!
June 29, 2010 at 8:11 pm
Wouter,
This can be accomplished by hooking into template_redirect as well as a few other places. I have outlined the process for custom post types here: http://wordpress.mfields.org/2010/custom-content-type-add-theme-redirect/
You should be able to adopt the same process for custom taxonomies rather easily.
June 29, 2010 at 8:14 pm
Excellent – looks good [Wanders off to run some tests…]
September 20, 2010 at 7:27 pm
Hey Lee! And is it possible to sort the terms of custom taxonomy? (I need to show terms in special order on the page.) Thank you!
September 20, 2010 at 7:57 pm
It depends what you want the order to be. get_terms() supports a second argument to specify the ordering, e.g.
$terms = get_terms('category', 'orderby=count');
There’s more details here:
http://codex.wordpress.org/Function_Reference/get_terms
I suspect what you’re after is a custom order, in which case you’d need to either hard-code the list of terms inside the page template – or look at storing some kind of meta-data against the taxonomy terms, and retrieving that and using it to sort – but that’s probably beyond the scope of this article …
November 3, 2010 at 5:31 am
Hey, was playing with this and it worked pretty well, except that it seems to be just displaying links to the taxonomies themselves. Working on a site with lesson plans and my archive for the taxonomy level using your code looks like this:
http://www.englishadvantage.info/testblog/lesson-plans-by-level
It lists both levels and under it “1 related article” which is just a link to the archive of each taxonomy. In other words it’s not linking to the posts, just the taxonomy tags.
November 3, 2010 at 8:37 am
I took a quick look, and it looks like you’ve sorted this now?
The brand-directory.php posted in the article does exactly what you’re after (If I’ve understood correctly).
November 3, 2010 at 12:09 pm
I consulted http://mondaybynoon.com/2010/09/06/wordpress-archive-pages-taxonomy/ and figured out a hybrid between the two.
Thanks. I love the look.
November 3, 2010 at 12:10 pm
Oh wait, sorry, Yes I sorted the problem.
Wrong link above! I was trying to get both an archive and a grid front page working and confused my links!
The archive is all your code with a modification because I didn’t change the subdirectories of my custom posts.
January 19, 2011 at 8:21 pm
that was great help! really thank you.
I created custom type posts and then add them a taxonomy to categorize them, your code gave me an idea how to fetch only post with specific term.
Keep up the great job 😉
March 8, 2011 at 10:27 pm
Simple Taxonomies plugin is good and works with WP 3.1 but I now prefer adding new taxonomies in functions.php because the minute you disable the plugin, all your custom taxonomies are nowhere to be found. I almost had a heart attack when I did this by accident but luckily all my custom taxonomies came back to life the minute I enabled the plugin again.
Good tutorial by the way. Thanks
March 22, 2011 at 9:45 pm
Thanks alot for providing this template. I’m using it on WP 3.1 and it’s working great. I’m wondering, though, if there’s a way to paginate the listing, so, say, only 10 terms show per page?
I tried including standard pagination for a query, but I couldn’t get it work. Thx
March 22, 2011 at 11:10 pm
Hi – I suspect that this is because your base WP entry is a “page”, and they don’t normally contain paginated content – they’re just static. I can’t think of any easy way around that ….
March 23, 2011 at 6:29 am
I use this for my custom taxonomies \ \
For reference, visit this http://codex.wordpress.org/Function_Reference/paginate_links
I set the number of terms to be displayed in Settings >> Reading
March 23, 2011 at 6:33 am
the code paginate_links( $args ) didn’t show up in my previous reply but anyways its mentioned in the WP Codex link I mentioned
March 23, 2011 at 9:55 pm
Thanks for that – must give it a try out …
March 24, 2011 at 4:10 pm
I’ll second that 🙂 thanks Marion. Any chance you could paste your code up at http://pastebin.com/
March 24, 2011 at 5:23 pm
No problem =)
Here’s the code http://pastebin.com/jEQ5v4qh, you can just define the css to fit your site…
July 16, 2011 at 6:46 am
(four months later…)
Thanks for the code, Marion. Unfortunately, I was never able to get it working; most likely because I was indeed trying to set it up on a page.
But on the bright side, I’ve worked out a solution! It’s not perfect (ie, I had to manually add the page links, but it does the trick
If anyone wants to have a look, see http://intercontinentalcry.org/peoples/
I’d be happy to pass on the code if anyone wants it..
May 5, 2011 at 7:14 pm
Hi,
Thanks for the tutorial. It is helpful.
Now I need additional two things for my special case. Using a hierarchal custom taxonomy associated with a custom post type, I need:
(1) To change the admin meta-box to a drop-down menu to make sure the post has only one term associated. The drop-down menu should show just the latest children terms, so let us say, for example, I have those terms:
Zone X
–> Package X (Zone X’s child)
—-> District X (District X’s child)
Zone Y
–> Package Y (Zone Y’s child)
—-> District Y (District Y’s child)
I want the drop-down to show only the latest children: District X and District Y.
(2) To automatically select all parents of a selected child term when saving the post. So, let us say the user chose District Y in my previous example, then both Package Y and Zone Y should be selected as well, behind the scenes.
Could you help me with that please, or point me out to any helpful reference?
Thanks in advanced,
May 5, 2011 at 8:15 pm
It’s not something I’ve come across before I’m afraid.
May 5, 2011 at 8:20 pm
I see. Thanks anyway, Lee!
August 4, 2011 at 4:44 am
Hi Lee,
Posted this a couple different places, including the WP forums. Thought you might have some insights… http://wordpress.org/support/topic/custom-taxonomies-hierarchical-is-what-im-trying-possible-best-approach?replies=1
Appreciate any help! 🙂
August 4, 2011 at 8:21 am
I dropped a quick reply on that thread.
August 4, 2011 at 1:46 pm
Thanks for taking the time to reply, Lee 🙂
August 24, 2011 at 12:43 pm
“However, for some time now WordPress has supported a concept called “Custom Taxonomies”. Which is a long winded way of saying “We’ll let you choose how your organise and present your posts – however you want”
Interesting interpretation of “long winded” you have there :p.
December 28, 2012 at 2:39 am
This is exactly what I am after but the file is no longer available – I tried recreating with the code you have above but I’m doing something wrong! Are you able to upload the brands-directory.php again?
Thanks in advance!
December 28, 2012 at 10:38 am
The downloads should be back now …
December 28, 2012 at 3:19 pm
Thanks Lee! Appreciate the speedy response!
Not exactly what I was looking for but thanks for the help! Trying to make a product page with thumbnails.
Thanks again!