Posts tagged ‘custom post types’

When to (not) use a Custom Taxonomy

Saw a post over on the WordPress Stack Exchange site a while back, and though I sorta went into it in my answer there, I figured it would make a decent topic.

Custom taxonomies are great. But they’re not great for everything. When designing a custom solution, it’s helpful to understand this in advance, so you can choose what goes where properly.

What is a Taxonomy?

According to Wikipedia, Taxonomy is the practice and science of classification. I like this definition a lot, because it really points out what you’re doing with taxonomies. You’re classifying things. Or better yet, grouping them.

That word is important: Grouping. You’re putting things into groups. The taxonomy is the sum of those groups.

In the case of WordPress, you’re putting posts into groups. Maybe they’re custom post types of some kind (actually, they probably are if you’re doing it properly), but they still fit into the wp_posts table, so lets call them posts. You’re grouping posts together.

Categories group posts together. Tags group posts together. The way that these two are used is somewhat different, but that’s the basic end result here, right?

The group itself is the important bit. Not the term, the term you use for that group is just a label. It has no real significance whatsoever.

Now, I know that we often display the term, and I think that this is what confuses people. The category or tag is probably a word, in English (or your own language), and words have meaning. So yes, it does matter when I add “php” as a tag, or use the “Rants” category. But what’s important to realize is that that word only has meaning to people, not to the computers, and certainly not to our data design.


Enter Postmeta, Stage Left

Let’s say I’m building a new site, and I want to make, say, television shows be a custom post type. TV Shows are a pretty good choice for this example, as well as what the original SE question was about.

What makes sense as a taxonomy for a TV Show? Title? Actors? Episode numbers? Season numbers? For each item, you need to consider whether it makes more sense as a taxonomy or as pure post meta, or (rarely) both.

Titles makes perfect sense for a taxonomy. You’re grouping all the episodes of that show together, and people will want to see an episode listing. So yes, it’s a taxonomy.

Actors also makes sense as a taxonomy. Actors act in many roles, it would be nice to see what various shows and episodes they’ve been in.

Season and Episode numbers is another one. Every show has it’s own season and episode number. Usually this is represented as Season 1, Episode 1, sort of thing. At first glance, season numbers kinda makes sense as a taxonomy, since you can pull all of season 1 out. But on further reflection, no it doesn’t, because it doesn’t stand alone. Every TV series has a season 1. We don’t want to pull out all season 1 shows from all series, it’s not something we’ll need to do. Same goes for episode numbers, when are we going to make a query based on episode numbers, to get all the first episodes of all shows? Makes no sense. These should be postmeta (or “Custom Fields” as some people insist on calling them).

The difference is one of grouping. For Titles and Actors, we’re grouping individual things together in a meaningful way that stands alone. Sure, our labels (terms) will have meaning to us humans, but not to the act of the grouping itself. The group is a natural one. For seasons, the grouping is meaningful, but less so because it’s shared among non-similar things (different shows). It doesn’t stand alone. You could get around that by saying that your term would be title-season# or similar, but it really makes more sense as postmeta, since the season and episode number, taken together, are unique to the item we’re storing.

Postmeta as Unique Information

That’s the difference: Postmeta is bits of information that are specific to the post item itself. Taxonomies are bits of information shared, in a meaningful manner, by many different items. Title is shared across all episodes of a TV Show, and defines a meaningful relationship to all those episodes. Season number is shared, but it’s not meaningful because all shows have similar season numbers.

Notably, there’s easy ways to order by postmeta, but not by a taxonomy. Ordering by a taxonomy makes no real sense, because lots of items will share the same terms in that taxonomy. If I have 20 items all with “foo” as a term in a taxonomy, then what am I ordering them by? They’re all “foo” items.

As for querying, I can query based on either postmeta or taxonomy, if I really want to. Ideally, I’d do both. For example, if I wanted Firefly, Season 1, Episode 13, then I could specify both a tax_query for title and a meta_query for “S01E13″ and get that one unique item. If I wanted all episodes of it in order, then I specify the tax_query for title and the meta query to select the season/episode metadata, then use the orderby to put them in the right order.

Choose Wisely

So if I can query by them both, but only order by postmeta, then what’s the difference? Why not use postmeta for everything?

Speed. Querying for a taxonomy is loads faster than querying for posts with certain meta information. Even better, I can use both to make things even speedier. The meta_query for S01E13 is going to be loads faster when I specify that title taxonomy, because now it’s only looking for S01E13 amongst Firefly episodes, not amongst all episodes of all shows.

The bottom line is that it’s best to use a taxonomy for attributes that a) define a natural grouping of your items, and b) which are natural labels and not inherently useful data to your methods. The title is not inherently a useful data (it’s just text, could be anything), but the episode number is a number which you will want to order by and display/change/set. You use that episode number for doing something.

Also, it’s perfectly understandable for individuals to disagree on any given example. There is no “right” answer, there’s only the answer that satisfies your own personal use cases. When designing your taxonomies, just remember to think about grouping of items and how you’re going to use the data you’re defining. If it’s a group in how you are going to use it, then a taxonomy works better than postmeta. But if you need the attribute to be manipulated in some manner, then a postmeta works better.

WordPress 3.0 and Custom Post Types

There’s been a lot of talk about custom post types, and I know many people are looking forward to it. Unfortunately, I think some (perhaps many) of those people are going to be disappointed. Custom Post Types might not be what you think they are.

I blame the naming, really. “Custom Post Types” makes the implication that these are “Posts”. They’re not. “Post Type” is really referring to the internal structure of WordPress. See, all the main content in WordPress is stored in a table called “wp_posts”. It has a post_type column, and until now, that column has had two main values in it: “post” and “page”. And there’s the big secret:

“Custom Post Types” are really Pages.

Sorta.

For a long time in the early days of WordPress, it just had Posts. But hey, no big deal, because it was just running a big Blog anyway, right? The Posts appeared on the Blog page (and in the Feed) in reverse chronological order. Each Post could appear on its own URL, using the Permalink structure.

Pages came along and changed that.

  • Pages don’t appear on the Blog. Or in the Feed.
  • Pages don’t even really have dates and times on them that usually get displayed.
  • Pages have their own URL at the root of the website, outside the Permalink rules.
  • Pages even have hierarchy in their URLs, if they want.

Pages, however, do live in the wp_posts table. So post_type exists to handle that. When WordPress is building the Blog, it looks for post_type = “post”.

Bring on the “Custom”.

Now we have these Custom Post Types. Or rather, custom post_types. Instead of “page” or “post”, we can have “custom”. Or “fred”. Whatever we like.

But how do these new post types get displayed? What do their URLs look like?

Well, these are custom, and they can be customized. You can give them their own space on the website. So if I want them to live at /custom/page-name, then I can. If I want them to have hierarchy, then I can do so. Justin Tadlock explains how they can be made to do this quite well.

But they are still not Posts.
They do not show up on the Blog.
They do not appear in the Feed.

This is a matter of definitions, really. See, the Blog is a reverse chronological order of the Posts. That it what it is defined to be. The Feed is basically the same thing, in feed form.

So all of you thinking of a custom “Podcast” post type, you’re in for a disappointment.

So what’s the big deal?

Well, all that said, custom types can have their own systems of doing things. They are custom, and as such, they are customizable.

If, for example, you wanted to have them appear on their own “blog” area, or in their own “feed”, then sure, that’s entirely doable. You can make a function to produce your custom feed. You can then call “add_feed” to add your feed. You can create single-type.php templates in your theme that will be used for your custom type. You could even make a “blog” out of your custom type.

And doing it the other way is possible too. You can adjust the “Blog” to show your type. You could change the “Feed” to show your type as well.

But these things are NOT the default way of doing things. There’s no code in there to do that, and there’s very likely not going to be. If you want your type in the Blog, in the Feed, then you have to do it yourself. The URL is NOT easy to customize and play around with. The rewrite system is unforgiving, and you have to stick within a set of rules for things to work well.

However, should you? Let’s say you make a “Podcast” custom type. You can go to the effort of putting them in the feeds and making them show special on the blog… but you could already do that with a “podcast” category. And it’s much easier to do a category and customize categories than custom types will ever be.

Something like 80% of the uses I’ve seen for “custom types” would be better served by making normal posts and using some existing method to separate them or to otherwise mark them as special.

So what are they good for?

What if you could install a forum on your site? bbPress is pretty good. But it could get all complicated to set up and such. Well, plugins are pretty easy. But all those forum posts have to go somewhere…

Custom Post Types is a way for plugins to define types of content for themselves.

A bbPress forum could store every post in the forum as its own custom post type quite easily.Or a wiki plugin could store each of its own pages as a custom post type. Things like that.

See, they’d get their own URL handling automatically, and they wouldn’t need weird database handling tricks.. It makes things much simpler and easier for those plugins to do their thing when they have the backend support for it in the core.

Some of you are thinking “Okay, so plugin authors can make better use of them. I won’t have to write a lick of code, I’ll just install a plugin that makes my type and handles the stuff for me.” And yeah, you can do that.

But then you’re wedded to that plugin. WordPress doesn’t know about your custom posts. If you remove the plugin, your custom posts are still there, but now they’re completely invisible. Can’t be pulled up, seen in the admin, the URLs all stop working…

Wrap it up, son…

Using custom post types right now is, for most people, a bad idea. Only specialized usages really exist for them… for now.

For the long term, WordPress will probably use them a lot more extensively. And plugins can make great use of them for all sorts of things. But you, as a user, probably don’t need to be messing with them. Not if you’re just creating a website or writing a blog. Not right now. Wait for the plugin and core development to catch up to the potential. Using them early leaves you open for a world of confusion and grief.