Custom Post Types, Custom Taxonomies, and Permalinks in WordPress 3.0

Posted: September 06, 2010 Comments(19)

Please Note: This article has since been extended. Please read more up-to-date information in Revisiting Custom Post Types, Custom Taxonomies, and Permalinks

Custom Post Types are a huge boon to everything WordPress. The feature has been long awaited, and lays a nice foundation for WordPress becoming more of a CMS to those still convinced it’s merely a blogging engine.

Custom Post Types, for those not familiar, is basically a templated content type based at their core off of WordPress’ Posts. There are a number of optional fields you can include within a Custom Post Type, and you can also build in your own. It opens the door to building a refined UI for data storage within WordPress given custom circumstances.

That said, you may be curious how that effects other systems such as Pods. If you haven’t had a chance, I discussed WordPress 3.0 and Pods in detail and have concluded that Custom Post Types and Pods achieve different goals at this point, and working with Pods gives you a level of control Custom Post Types currently do not (and in part do not strive to) achieve.

As full disclosure, I’ve recently been accepted as a Pods Core Developer but hope to express that circumstance having no effect or any biased opinions toward Custom Post Types. The Pods team wouldn’t exist without WordPress, and we’re all super thrilled about the existence of Custom Post Types.

In this walkthrough, I’d like to cover a fully top-to-bottom implementation of Custom Post Types, specifically targeting the task of ensuring a pretty permalink structure for your single pages. A follow-up article will take into consideration custom taxonomies for archive-style pages.

Up and running with Custom Post Types

Perhaps the biggest outstanding learning curve with Custom Post Types is the implementation itself. While programmers will love it, less experienced theme developers are likely to become quickly frustrated with the initial setup of Custom Post Types. While there is a lot of information in the always useful Codex, Custom Post Types still require an understanding of WordPress established conventions for implementation.

I’m a stickler for understanding the ins and outs of a system in which you work professionally, but I also understand that WordPress is a fantastic platform for tinkering. That said, if you’re a professional you’re looking to save as much time as possible. If you’re a tinkerer you’re looking to get up and running as quickly as possible so (hopefully) you can dissect how it happened. Given that, a really nice way to rapidly set up your Custom Post Types is the Custom Post Type UI WordPress plugin. Custom Post Type UI completely removes the tediousness of setting up Custom Post Types by providing an interface within the WordPress admin to do so. I’ve been using it on all of my recent projects and it’s a huge time saver. I do recommend though, that prior to using the plugin, you take the time to really understand what Custom Post Types are and how they fit into the big picture.

For the purposes of this walkthrough, we’ll set up an informational DSLR site with some information about a few cameras. Using Custom Post Type UI, we’ll set up a Cameras Custom Post Type:

Initial setup of the Custom Post Type

While you can create a Custom Post Type filling out just the fields above, we’re working for a full implementation here, so we’re going to fill in the Advanced Label Options too:

Setting label options

If these fields are not populated, defaults will be used based on the initial labels used to set up the Custom Post Type. In this particular case, using those defaults would have worked out just fine, but there will be circumstances where a revised nomenclature will be much more meaningful to clients. We’re also going to customize the Advanced Options offered by Custom Post Types/Custom Post Types UI:

Setting Advanced Options

Using these fields we’re able to further refine the attributes of our Custom Post Type. Many of these can be left as default, but we’ll pay particular attention to both the Custom Rewrite Slug as well as the Supports areas. Built-in Taxonomies are also important, but we’re going to revisit that later. The Custom Rewrite Slug is responsible for ensuring your permalink structure remains accurate and in tact. More on that during implementation. Now that our options are set, clicking Create Custom Post Type will add our Custom Post type to the admin UI:

Custom Post Type in the admin UI

Adding a new entry will provide a familiar, but customized content entry view:

Adding a new Camera

Once we’ve added some entries, we’ll begin building our library of content:

Content added to Custom Post Type

With Custom Post Types comes all of the built in content management functionality of WordPress, but at this point, we’ve got nothing to show for it within our theme; these pages are nowhere in sight on the front end. Our first option could be to use WordPress 3.0 Menus and manually build out a navigation system with a series of Custom Links, but that would quickly become overbearing given the fact that we’re hoping to build a website with hundreds (or thousands) of content pages.

Structuring WordPress for Custom Post Types

Custom Post Types are just that, they’re a collection of content. For the sake of organization as well as user experience, there should be some sort of hierarchy that incorporates your Custom Post Types. Currently, if you were to hit one of our Camera pages using the Permalink outlined on the edit page, you’d see the content included in the post:

Viewing an entry

Custom Post on the front end

For the purpose of this example, the permalink we’re working with is http://wordpress/cpt/cameras/canon-7d/ which is just fine; I like the way it’s structured. The trouble creeps in when, by experience, we want to view an index page by stripping off the last URL segment and trying to hit http://wordpress/cpt/cameras/. Out of the box we’re slammed with a 404 error. As a fix, I’d suggest creating a WordPress Page called Cameras (with the proper slug) to ensure we no longer hit that 404.

This ties into my philosophy of structuring WordPress sites; WordPress Pages should dictate the overall structure (for both content and URLs) and be the foundation of everything built on top of it. To our benefit, Custom Post Types work within thsi philosophy.

With our http://wordpress/cpt/cameras/ URL now properly resolving, we could create a custom Page template to pull in all of our Cameras. There are two approaches here, you can either set the Page Template in the Page Attributes sidebar on the edit screen, or simply name your template file using the Page slug. We’ll take the latter approach and create a new file within our theme directory called page-cameras.php consisting of:

<?php

/* Template Name: Cameras index */

get_header(); ?>

  <div id="container">
    <div id="content" role="main">

      <?php
        query_posts( 'post_type=cameras' );
        get_template_part( 'loop' ); // looks for loop.php which is specific to Twenty Ten
        wp_reset_query();
      ?>

    </div><!-- #content -->
  </div><!-- #container -->

  <?php get_sidebar(); ?>

<?php get_footer(); ?>

Note: The call get_template_part() looks for loop.php, a template file specific to Twenty Ten, the stock theme that ships with WordPress 3.0

What we’re doing in this template is simply querying all posts for our cameras Custom Post Type and sending that data to The Loop. Last, we reset to the original query fired during page creation which will prevent any funkyness with sidebar and/or footer logic. What results is a page that mimics a default Posts entry view in Twenty Ten:

Cameras index page

While the implementation so far is great for including the data stored in our Custom Post Type, it’s not very organized.

Organizing Custom Post Type data using a Custom Taxonomy

Closely related to Custom Post Types are Custom Taxonomies. To our benefit, the Custom Post Type UI plugin handles the creation and maintenance of Custom Taxonomies as well. We’re going to organize our Cameras Custom Post Type by attaching a few Taxonomies:

Taxonomy setup

Taxonomy settings

When creating them, we’ve attached the Taxonomies to our Custom Post Type, and they now show up as expected:

Custom Taxonomies in the UI

Out of the box, Custom Taxonomies behave like tags. Depending on how you’d like to use your Taxonomy, tags might be an applicable solution. In this case, however, I’d like to offer a choice-based system for my client. To do that, and therefore make your Taxonomy behave more like a WordPress Category, you’ll need to edit the Advanced Options of the Taxonomy:

Hierarchy option

By setting your Taxonomy to being hierarchical you’ll provide a listing of all existing entries as well as a check/uncheck interaction:

Taxonomies

As with most things Custom Post Type, while you’re able to add/edit/remove the data, it doesn’t do much out of the box on the front end. Viewing the Canon 7D page we just edited on the front end results in no visible change. We’re going to use our Custom Taxonomy to provide category-style archive listings.

The end of the basics

This walkthrough sets the stage for the more difficult task of setting up Custom Taxonomy-based archive-style pages using appropriate permalinks. If you’d like to take the next step in pushing your Custom Taxonomies to the front end of your site check out WordPress Archive Pages Based on Custom Taxonomies.

Get my newsletter

Receive periodic updates right in the mail!

  • This field is for validation purposes and should be left unchanged.

Comments

  1. Great post Jonathan and congratulations for being added as a Pods Core Dev. I still think Pods is going to help you do things easier for certain things.

  2. Im having trouble trying to create a list of custom post types inside of a custom taxonomy. For instance, I want to have a list of associated posts in a particular category but the category is a custom taxonomy and the posts are a custom post type. What would be the code to list just titles with links from the associated category?

    also, is there a way to define the current category in a custom taxonomy? Let’s pretend that there is always only one category in each taxonomy associated with each post. I want to define the current category within a defined custom taxonomy… Is there a way to do that?

    These custom posts/taxonomies have me scratching my head a bit…. lol!

  3. Out of the box we’re slammed with a 404 error. As a fix, I’d suggest creating a WordPress Page called Cameras (with the proper slug) to ensure we no longer hit that 404.

    Hello Jonathan,

    if you receive a 404 Error after you create your new custom post type, try to ONLY VISIT “Permalinks” under your Options page in Admin area. This will update the permalinks. Let me know if it works. 😉

  4. Hello. Thank you for the great tutorials. I used the Custom Post Type UI plugin to create a “News Articles” custom type. The rewrite slug is set to “news” and my Permalink Custom Structure is “/%postname%/” so articles are available at http://www.example.com/news/my-article-slug. This works great.

    However, I would now like all of my “Posts” to be prefixed with blog/ in the URL (e.g., http://www.example.com/blog/hello-world). I tried changing my Permalink Custom Structure to “/blog/%postname%/”, but then all my news articles also have “blog/” prepended.

    Is there a way to accomplish this? I thought about creating another custom post type called “Blog Posts” with the rewrite slug set to “blog” and then discontinuing use of the original “Posts” type, but it seems there would be a better way.

    Thank you.

  5. Hello Jonathan.

    Thank you for the suggestion, that I’ve found much useful to learn to manage custom post types and to resolve some problems I’ve had.
    Adapting your instructions to my situation (that it’s a bit different archiving problem, but adaptable) I am able to display exactly in the page that I want all the posts of the custom post type that I want. Have some details in the way to show the post that I need to change, but it work. My problem now it’s to extend this structure to all the other custom post type that I have, some dozens. The simplest way to make this it’s to write a page template for every custom post type and select him like template in the attribute page, like made for the first custom post type. But I have towo problems to make this:
    1) I think are a lot of duplicate code lines; 2) in the attribute page I can’t visualize more than four page template…indeed I tried to create more, but also if I have this files in the theme folder, I continue to visualize only four between the page template.
    Have you idea about what happen? Why I see only four? Have you idea about the way to make the first template to work for all custom post type?
    In theory I think could be possible, giving like post type, instead of a “static” name like “cameras” the name of the custom post type, isn’t it? Probably exist a variable that you can assign the value of the custom post type that is quering in a particualr moment? Sorry, but I am an absolute beginner of wordpress and PHP, I don’t know like they work and I’m just learning.

    Have a nice day.

  6. Hi Jonathan.

    About my previous post, I have to correct myself about the problem number 2: indeed it was because of a my mistake that I didn’t see more than four page template ( I didn’t write “Template Name:” at the begininng of the template)…now it’s ok.
    What still miss it’s an answer to the problem number 1: I think are a lot of duplicate code lines.
    So, also if now I am able to continue in my work, I have the curiosity to make this better.

  7. Robert,
    What happens if you use /%category%/%postname%/ as the permalink where “blog” is the category?

  8. Hi Jonathan,

    Great tutorial. Have you discovered where the Custom Post Types UI stores the code? I’ve looked in the functions.php file but it does not seem to reside there. Any ideas?

    Thanks, JK

  9. WordPress core will support much more integration with Custom Post Types in version 3.1, as it stands they aren’t integrated into the template system to a great degree, but that’s coming!

  10. Custom Post Types UI doesn’t store the code anywhere, really, it builds out what’s needed at runtime based on the options you’ve entered. If you’re looking to find out how to build Custom Post Types by hand (which I definitely recommend) I would suggest checking out the Codex

  11. Thanks Jonathan, been busy with Taxonomies and what not after a upgrade from ClassiPress that moved my URLs to a different structure.

    Great article, have to really dig in to see IF I can keep my urls as they were or not.

Leave a Reply

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