Custom post types in WordPress

One of the things I’ve been hoping would be implemented in WordPress for years is the ability to create custom content types. The inability to do this has been WordPress’ weakest point when compared to rivals in the CMS market.

In WordPress 3.0, we’ll have the capability to easily create and manage content via custom post types. With a few lines of code in a plugin, you can have your own types.

There are other 3.0 features such as menu management and multi-site, but this is the most promising feature coming. In this tutorial, I’ll walk you through the creation of custom post types and how they can be used for your blog.

Note that I’ll use “post” and “posts” a lot to refer to custom post types in this tutorial. I’ll try to separate this from what you likely know as a post by calling it a “blog post.”

What are custom post types?

Don’t be confused by the term “post” in the name. It is actually an extremely generic term and should not be considered the same thing as a blog post. If you prefer, you can replace it with “content” instead.

Custom post types don’t have any strict rules that define what they are. They can represent any type of content you want. For example, WordPress ships with several default post types.

Blog Posts

Pages

Attachments

Revisions

Nav Menus (WordPress 3.0)

You should think of them as a way to create, edit, and store information in the same way as blog posts but with much more creative control.

One thing I would warn against is trying to separate your blog posts in this way. You have categories, tags, and custom taxonomies at your disposal if you’re just looking for a way to label them.

Ideas for custom post types

While WordPress ships with some good default post types that are great for most sites, some of us need alternatives. I’ll list some things below that I think would be useful and link to examples if I can.

Don’t let your imagination be limited by my list of examples. Also, look for some information on the forum and ticket system ideas from me in the future. Those two are projects I’ve been building and would love to get some feedback on.

Custom post types in the admin

Once you create a custom post type, WordPress can handle all of the admin stuff for you. By default, the administration interface will be the same as what you get with blog posts and pages. Of course, you’re welcome to get more advanced with it and change it into whatever you like.

In this tutorial, I’m creating a post type called Super Duper. With the minimum post type settings, the admin will look like the screenshot below (click image for more detailed view):

Creating custom post types (basics)

WordPress 2.9 introduced the register_post_type() function. It didn’t do a lot at the time, but WordPress 3.0 will make this a powerful tool.

To get the basic functionality of a custom post type working, we hardly have any code to input. Before you start, you at least need a few things: a name, two labels, and whether your post type will be public (you’ll likely want this).

When creating custom post types, you need to add your code to a plugin file. While it’s possible to do this via the functions.php file in a theme, it is incorrect to do so.

You’ll notice that there’s not a lot going on there. We added two parameters: a post type name and an array of arguments. All of the possible arguments are detailed in the next section.

If all you’ll ever want to do is something as basic as having a title field and content textarea, you can skip over the next portion of this tutorial.

Creating custom post types (in detail)

In the basic section above, we used two arguments to create our custom post type. However, the register_post_type() function has well over 20 arguments you can use. It gives you a lot of control over the specifics of your post type without a lot of hassle. You can mix and match these in all sorts of ways that I can’t even come close to covering in this tutorial.

Below, I’ll describe each of the arguments available for use. Each section will have an example of how to add the argument to the arguments array.

labels

The labels argument is an array of strings that represents your post type in the admin. Each string is a bit of text shown for particular function in the admin. By default, non-hierarchical post types will have text with “post” in them and hierarchical post types will have text with “page” in them.

It is particularly important that you make these strings translatable if you’re creating a plugin for public use.

This list is a set of general examples of when each string is used. However, each may be used in multiple places in the admin.

name: The plural form of the name of your post type.

singular_name: The singular form of the name of your post type.

add_new: The menu item for adding a new post.

add_new_item: The header shown when creating a new post.

edit: The menu item for editing posts.

edit_item: The header shown when editing a post.

new_item: Shown in the favorites menu in the admin header.

view: Used as text in a link to view the post.

view_item: Shown alongside the permalink on the edit post screen.

search_items: Button text for the search box on the edit posts screen.

not_found: Text to display when no posts are found through search in the admin.

not_found_in_trash: Text to display when no posts are in the trash.

parent: Used as a label for a parent post on the edit posts screen. Only useful for hierarchical post types.

description

The description argument allows you to write a text string of your post type. Thus far, I haven’t seen this used anywhere in the WordPress admin, but I’m sure custom post type plugins could take advantage of this.

'description' => __( 'A super duper is a type of content that is the most wonderful content in the world. There are no alternatives that match how insanely creative and beautiful it is.' ),

public

The public argument is a kind of catchall argument for several other arguments and defaults to false. Depending on whether it’s set to true or false, it’ll automatically decide what other arguments should be unless they’re specifically defined. If you’re looking for finer control over the public arguments, there are three specific arguments you may set:

show_ui: Whether to show the administration screens.

publicly_queryable: Whether queries for this post type can be performed from the front end.

exclude_from_search: Whether the posts should appear in search results.

menu_position

By default, a new post type is added after the Comments menu item in the admin. But, you have to ability to move it to a position more suitable for you. Default WordPress menu items are set apart by integrals of 5. For example, using 20 will add your menu item after Pages.

'menu_position' => 20,

menu_icon

New post types will default to the Posts menu icon, but if you want to mix it up a bit or give your post type some separation from other elements, you can define a custom icon. You only have to input a a custom URL to an image file.

hierarchical

The hierarchical argument allows you to choose whether you want your post type to be hierarchical. It defaults to false. If you set it to true, your posts will behave like pages in WordPress.

'hierarchical' => true,

query_var

The query_var argument allows you to control the query variable used to get posts of this type. For example, you could use it with the query_posts() function or WP_Query class. This will default to the name of your taxonomy.

'query_var' => true,

capability_type / capabilities

The capability_type argument is another catchall argument for several more specific arguments and defaults to post. It allows you to define a custom set of capabilities, which are permissions to edit, create, and read your custom post type. If you’re unfamiliar with capabilities, I highly recommend reading my guide on users, roles, and capabilities.

If you just want to keep the same permissions you have with blog posts, leave this at the default. Otherwise, you can either set capability_type to something custom or define each specific capability in the capabilities array.

edit_post: Whether someone can create and edit a specific post of this post type.

edit_posts: Capability that allows editing posts of this post type.

edit_others_posts: Capability that allows editing of others posts.

publish_posts: Capability to grant publishing of these types of posts.

read_post: Capability that controls reading of a specific post of this post type.

read_private_posts: Capability to allow reading of private posts.

delete_post: Capability that grants the privelege of deleting posts.

For most people that need control over these things, it’s easier to just change capability_type to something like super_duper. WordPress will automatically switch the other caps to follow this pattern. For example, the edit_post capability would become edit_super_duper.

Of course, capability control means nothing without being able to choose who has the capabilities. That’s what my Members plugin was created for. It’s ideal for this scenario.

supports

The supports argument allows you to define what meta boxes and other fields will appear on the screen when editing or creating a new post. This defaults to title and editor. There are several available options:

title: Text input field to create a post title.

editor: Content input box for writing.

comments: Ability to turn comments on/off.

trackbacks: Ability to turn trackbacks and pingbacks on/off.

revisions: Allows revisions to be made of your post.

author: Displays a select box for changing the post author.

excerpt: A textarea for writing a custom excerpt.

thumbnail: The thumbnail (featured image in 3.0) uploading box.

custom-fields: Custom fields input area.

page-attributes: The attributes box shown for pages. This is important for hierarchical post types, so you can select the parent post.

rewrite

The rewrite argument allows you to define the permalink structure of your posts when viewing the single post. For example, you may want to have a structure like yoursite.com/cool/post-name. WordPress will set up a default structure based on your taxonomy name. The rewrite argument can be set to true, false, or an array of values. It takes two arguments:

slug: The slug you’d like to prefix your posts with.

with_front: Whether your post type should use the front base from your permalink settings (for example, if you prefixed your structure with /blog or /archives).

'rewrite' => array( 'slug' => 'cool', 'with_front' => false ),

taxonomies

If you have some preexisting taxonomies, you can allow posts of this type to also use those taxonomies. You just have to set an array of taxonomy names that you’d like for it to use. WordPress will handle all the administration features for you.

Note that I’ll be covering the integration of post types and taxonomies in more depth in a future tutorial.

'taxonomies' => array( 'post_tag', 'category '),

can_export

You can use the can_export argument to decide whether posts of your post type can be exportable via the WordPress export tool. By default, this is set to true.

'can_export' => true,

register_meta_box_cb

This feature will likely only be useful to developers. You can create a custom callback function that is called when the meta boxes for the post form are set up.

'register_meta_box_cb' => 'your_callback_function_name',

permalink_epmask

I won’t pretend to know much about permalink endpoint masks. I just know you can define a custom one for your post type. Most of you won’t need this. For the purposes of this tutorial, I’ll leave this at the default.

'permalink_epmask' => EP_PERMALINK,

Viewing a custom post type

WordPress will show the singular view of your custom post types without any extra work. Once you create a new post, you’ll be able to view it by clicking on the View Post link.

If your WordPress theme has a single.php template, this will be used to display your custom post type. If not, it will fall back to the index.php template. Since this is a “custom” post type, I’ll assume you want to customize how it’s output. To overwrite the default, you can create a custom template. Our template will be called single-super_duper.php.

You can go as crazy as you like with this template. All of the standard WordPress template tags will work just fine here as well. I could give you endless pages of examples of how to customize this, but I won’t. I’d rather allow you to get creative on your own.

If you’re using a smart theme like Hybrid, this template will be super_duper.php. Hybrid has long supported custom post types and uses a different template hierarchy, which is detailed in its tutorials. WordPress 3.0 will be a fun time to use this theme because of the ultimate control it gives you over templates like this.

Showing multiple posts from our custom post type

Let’s suppose I wanted to show the 10 latest “super dupers” I’ve published. We’ll use the standard WordPress loop for this and customize it however we like. Here’s a basic example:

Obviously, this is an extremely simple example. Understanding what you can do with the loop is outside the scope of this tutorial. The most important part is giving the post_type argument the name of our post type.

Getting the post type of a post

An old, yet useful, function in WordPress is get_post_type(). It allows you to check the current (if no post object or ID input) or a specific post’s post type. It will return the name of the post type for the post as a string.

$post_type = get_post_type( $post_id );

Checking if a post type exists

WordPress 3.0 will introduce a conditional tag called is_post_type() whose purpose is twofold. Its first purpose is to check whether a post type or types exist. In order to use it, you can input a custom post type name or array of names into the function call.

Checking if a post is of specified post type

The second purpose of the is_post_type() function allows you to check a specific post against a specific post type(s). Let’s assume we want to check if one of our posts has the super_duper post type.

if ( is_post_type( 'super_duper', $post_id ) )
echo 'This is a not a blog post. It is a super duper!';
else
echo 'This is not a super duper. [insert sad face]';

Checking if a post type is hierarchical

You may want to treat hierarchical post types differently than other post types. To figure out if a post type is hierarchical, you can use the is_post_type_hierarchical() conditional tag. It will take in a post type name, post ID, or post object as its single parameter.

if ( is_post_type_hierarchical( 'super_duper' ) )
'Super Dupers should not be hierarchical!';
else
'Super Dupers are definitely not hierarchical! We stick it to the man!';

Getting a post type object

In some scenarios, you may want to get the arguments (all those things we went over earlier) for a specific post type. It is extremely important for plugin/theme authors to respect these arguments when creating plugins/themes that interact with custom post types.

Let’s suppose we want to call a specific function if the super duper post type has set show_ui to true.

Adding and removing support for post type features

The add_post_type_supprt() function is no different than using the supports argument when first creating your post type. This is likely more useful if you’re using a plugin/theme that has defined a custom post type.

So, let’s suppose you’re using a plugin that creates a new post type for you. Your post type doesn’t have support for thumbnails, but you think this feature would work well on your site.

add_post_type_support( 'post_type', 'thumbnail' );

The opposite of this function is remove_post_type_support(). So, let’s further suppose that your plugin author added support for excerpts, but you don’t want to use this feature.

remove_post_type_support( 'post_type', 'excerpt' );

Checking if a post type supports a specific feature

As a plugin/theme author, this will likely be useful. You wouldn’t want to try and display stuff that doesn’t exist for a custom post type. For example, your theme may wrap post content with a <div> or something of that sort. This is fairly common. But, you may want to remove it if the post type doesn’t have written content.

Help! I’m getting a 404!

If you’re getting a 404 message when trying to view a post, don’t worry. This is supposed to happen when setting up new post types. The easiest way to fix this is to simply visit your Settings > Permalinks page. You don’t have to save your permalinks but just visit the page. This will flush your rewrite rules.

If you’re a plugin author, you can save yourself some support questions by flushing the rewrite rules on activation of your plugin.

Is this a theme or plugin feature?

I’ve had a hard time trying to decide which to call it, and have ultimately decided that it’s both. It’s a marriage of the two because both need to be in sync to fully enjoy the benefits of custom post types.

More than likely, you’ll see post types registerd from within a plugin. But, they have to be displayed by your theme. If you’re creating this all yourself, you can simply drop it all in your theme.

If you’re a theme author, you should be aware that plugins may add new post types. Do yourself and your users a favor by not assuming too much. Keep your code flexible enough to give a default view for custom post types and easy enough to handle when creating custom templates for those post types.

The tip of the iceberg

I haven’t even scratched the surface of what’s possible with custom post types. Even the new navigation menus feature of WordPress 3.0 will be built with them. While I know some people in the community don’t agree with this decision, I wanted to point it out because it’s a unique example of what’s possible.

Of my list of about 1,000 things I wanted to share in this tutorial, I might have covered about 20 of them. Given enough free time, I could write a book on using custom post types. Some stuff should be left open to exploration though, and I encourage you to try everything I’ve written about and move beyond this tutorial to creating something unique for your site.

616 Responses

Well wordpress has certainly come a long way since the start and i love all the new features they keep churning out with most updates. I still believe they are the best content manager system for beginners.

Now post types, precisely because they are so easy to make and use, can give you headaches. Here is a scenario I found myself in the other day:

I installed Brad’s plugin and started playing around. I made a new post type, and published two new posts. Then I decided I did not like that post type and that I was fine with the two default WP types, Posts and Pages. So I deactivated the plugin, and my two posts disappeared! 😮

Which, in a way, is inconsistent with what people are use to in other parts of WordPress. For example, if you delete a category, everything in it is assigned to the default category. So, maybe you expect that something similar will be the case with post types too. But it’s not.

After CPTs are created, how does one navigate installing plug-ins that apply to regular posts? For example, I have a plug-in that converts regular posts to Eventbrite compatible events, how do I get the plug in to apply to the special ‘Event’ type post instead of regular ones?

Thanks for this timely and in-depth article. I needed this information right now for a client site who wants to create a directory site for bands, listing their profiles. I’m in over my head, but this article will help. Thanks again!

Thanks for linking to your plugin. I’m pretty sure it’s somewhere on my list of the other 9,000+ things I didn’t cover. I downloaded it a while back and keep meaning to poke around in the zip folder sitting on my desktop to see what the code looks like.

There is also CMS-Press which does a lot of the same as the plugin you mention. Both allow you to create taxonomies and assign them to any post type you create. Neither, to my knowledge, yet allow you to do the same for meta boxes which would be a sensational aspect to add.

In both cases I think that proving the concept of UI based management for post types, taxonomies and meta boxes via plugin is important, and equally something that should make its’ way into core (or canonical at the very least).

Great tutorial. This is definitely one of the most exiting features of 3.0.

Ultimately it’s the user that will benefit from this because as themes developers we wont need to set complicated metadata up and explain how to use them, we will just create the appropriate post type that will handle everything seamlessly.

First off Justin, excellent guide. I also like the idea of calling them custom content types. However, even after this guide, I still don’t get it. I hear people describe custom post types and all I can think about is why not use categories, tags, etc as they seem to address the problem already. What are the differences between using that and this custom post type stuff? I don’t understand the limitations of how the current system works via pages, posts, etc versus custom post types.

Here’s a good rule of thumb: If it can be a blog post, it should probably be a blog post. Most of us get stuck in this “blog” mindset so often and think of things in terms of posts and pages. But, in reality, other types of content don’t have to be nor do they need to be defined by the strict rules set up for posts and pages.

Let me propose a counter-question: Why have pages and attachments if they’re really just posts?

In the “Ideas” section early in the article, I mentioned creating a forum with a custom post type. You wouldn’t want to lob all those forum topics in with your blog posts, would you? Of course not. You certainly don’t do this at WP Tavern. You’d want your forums as a separate section of your site. You’d want a forum-friendly permalink structure. You’d want to set up custom forum-type stuff for it.

I really seems obvious at first to separate in different post type, but I´m also trying to understand what else do I (not a programmer) have to do to use them.
Two things are not clear to me yet:
1. Sharing tags, I created a tag taxonomy for my new post-type, but it´s no shared with posts and pages. So far I learned you can share a new taxonomy with different post-types, but can you share the tags (and categories) too?
2. The new custom menus for 3.0 are great, and different categories are already listed to be used as menu items, but what about custom post types? I have the new taxonomies I created and also the individual items in the new post-type, but not the whole list like I would automatically have if I used choosen to separate it as a category.

I recently created a site for a horse farm using wordpress. They list all the horses as posts, and the owner can’t create the new listings as she has SEVERELY limited computer skills. Each horse needs birthdate info, breed, and heritage info.

Now I can create a new post type with info boxes for the Name, birthdate, breed, heritage and other info. She can fill these in and I can output a nicely formatted ‘post’ for her without her being able to mess up the formatting.

when you create new post types, do they get stored in the posts table?
if that’s the case, I don’t think it’s very efficient for any kind of database driven application.
If you’re using a relational DB, then it should use normalization, primary and foreign keys,etc…
I think that’s something that PODS does.
for example, if you have movies, actors, genres, etc… how is this translated to the DB schema?

Actually, normalization of database schema is slower. By a long shot. Many table JOINs are expensive as heck.

The purpose of normalization isn’t efficiency; the purpose is for data integrity. When your data is normalized and you have proper foreign keys and constraints and such, then it’s possible to ensure that you never enter invalid data.

In this case, that’s not the primary goal, because most any type of data you could enter would be valid. So efficiency and speed-wise, it’s faster to store all the posts (regardless of type) in the same place. Good indexing solves the speed issues. And your JOINs are greatly reduced when you’re not having to pull from multiple tables to retrieve multiple types of things.

Yes, it’s usually quicker if you can avoid using joins. Custom post types by themselves don’t need joins since they’re in the posts table.

However, custom fields do require table joins…

I’ll go out on a limb and say that a lot of people are going to want a unique set of custom fields for each post type. Not only that, but they’ll want to filter based on one or more of these custom fields.

For example, for an “Event”, you may need custom fields for latitude, longitude, end date, address, speakers, etc. What if you only want to show events within a certain lat/lng range?

For these situations, Pods is *vastly* more efficient since you’re only querying a single table. With Pods, all the (non-relationship) fields for an event are stored in a single row.

On the other hand, WP needs to JOIN with the postmeta table (at least once). Since postmeta data is always LONGTEXT, indexing is a huge challenge and the data isn’t subject to any MySQL optimizations.

I, too, was having problems with pagination on a page template with my custom post type. However, I discovered that you cannot create a Page using the same string name as your registered custom post type.

For example, if you register_post_type(‘podcast’); you cannot then go create a Page called Podcast and expect it to still work with pagination. Either changing the name of the Page or the register post type string will fix your problem.”

I have the same problem, and I could/can fix it as Matthew Muro describes it. But I really WANT to have the same name for the page as for the slug of the custom post type. In my case it’s “work”. Is there no possibility to make this work?
Would be sooooo great of you (or anybody else) to help me out! Thank you very much.

Awesome tutorial. One thing I frequently use wordpress for is basic e-commerce. Usually I use pages as products with a custom template and custom fields for things like prices. Is there anyway I can add an extra input box for “price” rather than forcing the user to to use the slightly more confusing custom fields? I don’t really care if the data is stored in a custom field, I just want the boxes to be easier to understand.

Also, how can I make a custom post type default to a specific template rather than forcing the user to keep selecting one?

Andy – Check out this tutorial on creating meta boxes with custom post types. The data is still stored in custom fields but it shows up in the admin area in code-defined ways. So you could have price, inventory, available sizes, etc all within a “product details” meta box that goes along with the standard description + photos in the editor window.

All stuff you *could* do before 3.0, just a lot easier to explain and tailor to terminology clients are familiar with now.

Jeffro – For me, I think the power of custom post types is that you can control which panels appear on the edit screen based on the type of content the end user is adding. Imagine creating a site for a client that needs an event log and customer contacts. Events & Contacts could be 2 new content types each with edit screens tailored for the type of content being added. The edit screen would have less clutter and would be less confusing to end users whose job is to simply add content.

I am beginning to get into them in a big way and am very to happy to see this post. The codex is slim right not on all of the options. It looks to me like the power will be in adding other content types as well, and I am not finding a lot of details on that. I am going to take a look at wp-includes/post.php and see if that sheds any light.

@MattW – Another option is to create a page template (page-{posttype}.php) that has a separate loop and display the contents of the post type as Justin has demonstrated above. This would be closer to using category-##.php if you were using posts / categories to achieve the same result prior to 3.0. The rewrite => ‘slug’ option even allows you to have ‘/toplevelpage/subpage/reallydeeppage/’ as the permalink so that you could have all your custom data types show up within the same area that you have the page permalink. This might require your settings -> permalink to be /%postname%/ I think.

I’m in agreement about the recent discussions on creating an index page for custom post types, or at least having an option to. At the same time though, not all post types need an index page. For example, pages and attachments don’t have one.

Right now, I just use a custom page template, which can allow pagination. I haven’t looked into making a feed for it yet though.

Justin,
Above you talk about adding pagination to a custom post type index page while using a page template. How are you doing this? I have not been able to get a 2nd (or 3rd) page on my twitter post type, only the first.

I, too, was having problems with pagination on a page template with my custom post type. However, I discovered that you cannot create a Page using the same string name as your registered custom post type.

For example, if you register_post_type(‘podcast’); you cannot then go create a Page called Podcast and expect it to still work with pagination. Either changing the name of the Page or the register post type string will fix your problem.

Do you have a screenshot of what the finished product would look like? I’m in the middle of working with a Wordpress-based website that I’m creating, and I am discovering that to convert my blogger blog to the Wordpress site has really messed up my blog posts…Is there any easy way to fix this without having to re-write each one?

I’ve really enjoyed using Magic Fields up until now, and supposedly, this makes Magic Fields obsolete.

However, I’ve run into a couple of roadblock here as far as doing client work:

1) I liked how Magic Fields made it really easy for clients to upload images into the custom fields instead of having to perfectly type a long and ugly URL. Looks like using Custom Post Types is a downgrade in that this functionality is now lost

2) If a site is using a home page slide show for blog posts and I want to mix some of my new Post Types in with the blog posts for the homepage slide show, even if I add the correct category using the Custom Taxonomy, my theme is not registering the custom posts as a regular blog post, so there does not seem to be an easy way to have these posts appear on the homepage slideshow.

If anyone has any ideas of how to overcome these 2 issues, that would be great.

If you can find the hook for you plugin, you can add the metabox to your own custom post types. just replace “post” or “page” with your custom post type name. this worked for me to add the Vimeo for WordPress functionality to my media post type.

I’m using Gravity Forms + custom post types to let users suggest their own events. Gravity Forms lets me set publish_status to Draft and although right now you need some basic coding skills , I’m sure Gravity Forms will have full support for custom post types and taxonomies very soon.

Yes, I think the Events Calendar has a lot of potential to roll out events-based websites. The problem is that it is still immature and has a few bugs, but I see the developers working very hard on getting this up to speed.

Thanks so much for your write-up on this subject! It is great to at least be able to understand a bit of all these new functions in the upcoming WordPress version.

I agree with for example Brad, that for an end-user the dashboard can become much more intuitive with using custom post types; normally it takes quite a bit of effort to let them understand what Posts exactly are, now you can just give them the exact name.

I have one question, that perhaps you can help me out with. As I am in Europe and (have to) make quite a few projects in multiple languages, how does this work for naming the custom post type? Take for example your “books” suggestion. In other European languages, books obviously is a different word. Is it possible to use get_text calls in naming the custom post type or not?

Which of the following do you think makes the most sense and a few questions on how to achieve…I am trying to create a custom post type that is “as close to completely idiot proof and self-explanatory” as possible. Using the scenario of creating a custom post type that stores quotes for display throughout the site (sidebars, etc).

1) Customize the text from ‘Enter Title Here’ to say “Enter Quote Author” so that I can use the title field to generate the quote slug. If I do not use the title field the slug gets generated as ‘auto-draft #’ and you lose the ability to quick edit / trash from the edit menu.

2) Register a post type with only a meta box (no title, editor) to capture all details (author, quote, author title, etc). What action / hook / filter to connect with to modify the slug generation to match a meta box field? How to specify a column in the edit table view should have the quick edit / edit / trash UI options applied to it?

Great post. One feature I haven’t seen covered anywhere in articles related to custom post types is a listing feature. Do you know if there is an implementation similar to wp_list_pages() or wp_list_categories() that has the power of those functions? Something like wp_list_super_dupers()?

I’m particularly interested in a function that would list your custom post types, create sublists for children, and echo classes (ie. similar to current-cat, current_page_item, current-cat-parent, etc.) for hierarchical and active relationships in a post or page method (depending on how you enable the custom field).

If there isn’t one, there desperately needs to be, in my opinion. That would seal the deal.

I don’t think there’s any equivalent to the wp_list_pages() function for other post types, but I’m not sure there should be either. What I mean to say is that I’d rather there’d be focus on making sure custom post types work rather than building extra functions for them (in core). Then, allow developers to extend them with functions like this.

On the other hand, in 3.1, I’d love to see some consolidation of functions into flexible, generic functions that can be used across any post type.

Great and very helpful post. I have my custom post type all set up, however, I was wondering how you get the correct category archive setup for these posts? Right now it’s only displaying posts from the blog.

I’ve noticed that creating a just one custom post type adds about 15 new rewrite rules. (18 or 19 if you use CMS Press or Matt’s wrapper for index page archiving –> #comment-188177)

My question is this. I have a current site, which I’d like to port to wordpress to handle the content, and I can foresee at least 10 – 15 different “custom post types” that I’m going to need to set up.

15 post types * 19 rules/post type = 285!

Is that number high? I’m worried about performance. The site currently gets roughly 1000 visitors a day, but peaks at 3k.

It’s curious that menu_icon was added to show in the left-hand-menu but something like editwindow_icon which displays the larger 32 pixel version (/wp-admin/images/icons32.png) along with the Add New / Edit [Post Type] Title was not.

I’m relatively new to WP and I’ve been looking for a solution to paginate custom post types for quite a while now with no success yet.
Your suggestion works to the point of displaying my custom posts list. However, pagination is broken. Using wp-pagenavi, only a box with “Page 1 of 0” show below the post list which I limited to 2 posts for testing. Using wp default pagination tags, nothing shows below the posts.

Other relevant details:
– I placed the query on a page template (see below), created a new page and chose this custom page as the template.
– This page is not my front page. It’s accessed by a wp_page_list menu item.

Isn’t it possible to paginate custom post types? I don’t believe so. I prefer to believe it’s my fault. Can someone please help me out of this problem? I’m almost throwing the towel. Thank you in advance.

Really helpful article to get me started on the WP 3.0 beta but I have one thing which I have been stumped on for a few days! Not sure if it’s something I am doing wrong or if it hasn’t been implemented in the beta yet!

Working completely I have :
domain.com/post_type_name/
domain.com/post_type_name/post_title

Is it possible to have :
domain.com/post_type_name/post_type_category/

This page would list all the custom post types that are within that category. I know I can create a Page for each Category and have a different WP_query on each page, but when this is dynamic and more Categories are added there is a problem!

Awesome tutorial. By far the best one I have found regarding custom post types yet.

I got the custom post type working for the most part and can query them just fine but I am having trouble filtering the posts using permalinks. In the left nav I did a list of the taxonomies to use as navigation but the permalinks arent working. They’re going to the 404.

I tried changing the slug to what you listed a couple posts up but that broke all of it.

I found it not too long ago and I don’t know if many people know about it yet. Anyone have a review for it? It does work as advertised, but only an expert would know if it goes about custom post types the right way. I’m curious…

One thing that I cannot grasp. When I first heard “custom post types” for WP I was very excited because I envisioned something similar to “Custom Content Types” that Drupal offers.

The most important feature being the ability to EASILY add custom fields to these content types. So the user who is writing the post would not only see “Title” and “Content” fields for a “Movie” post type, but would also see “Actor” “Director” (etc.) fields where they can easily input the info and it would be displayed in the main body of the page with the content.

I don’t see how Taxonomy solves this. They are still just tags and do not appear in the main body of the post.

This is the main reason I must use Drupal for some jobs instead of WP. Some clients need many custom content types (Events, News, Reviews) that need specific fields they can easily fill out and then be displayed.

I am probably missing something, but adding Custom Fields to a new Custom Post does not seem like an easy task via the control panel…. lots of code customization? I hope I am wrong.

If by adding ‘actor, and director’ in the admin panel, you mean simply adding in the name of the actor and director, then taxonomies are perfect for that. It’s fairly simple to get the taxonomies related to a given post to show up on a page. Check out Justin’s movie post and you will see it in action exactly as you described.

Now if you are talking about giving the user the ability to also assign meta data to the actor such as a picture and description as well, then…

currently I only see 2 possible solutions to this issue, which is exactly what I am working on myself.

I have only just begun to play with that plugin, but it looks like it is almost perfect for the job. I only wish the author would have given some clear examples of how to implement it. Right now it’s more for php jockies than regular users.

This one I have actually had a bit of luck with, and can see some serious potential, esp since Scribu wrote it, and he’s the master when it comes to post_types. Give it some time though, as it’s only a few days old.

Either one, or a combination of the two, should accomplish 95% of everything your mentioning. Especially when Scribu adds the ability to edit one post_type within another post_type admin panel.

If these don’t fit your needs, check out pods. It does exactly what you are after, and 10x more. For me at least, I prefer for now to stick with native wp functionality, and frankly pods was above my pay grade lol..

If you create a type for example called portfolio and your example content might /portfolio/postone/ should you be able to view anything at /portfolio/ like an archive or something or do you have create a page and fake it.

Driz, this is exactly what I’m trying to figure out… I tested many possibilities, but without sucess until now. I have 3 post types. I created different template files for each one of them, the content opens perfectly, like /event/staff-meeting. But when I try just /event/ to have a list (loop) of all events of that post type, I’m not getting sucess. Someone knows how to make this possible?

Afff… Finally I got an answer to this! Permalink structure for pages is actually what we want. A page called “Event” will have /event as its permalink (since ‘event’ is its slug). What I did was, create a page and call it “Event”. Making use of WP template hierarchy, I created a file and called it page-event.php. And then I placed my post-type query for events in it:

Honestly… you’re a genius. I’m in the process of building my first web site (wordpress platform) and this info is priceless. I think I will print the page to have it close by. Thanks for the info. I’ve bookmarked your site and I will surely return.

along with almost everyone else, we’re really looking forward to custom post types in WP, but we’ve got some niggling doubts about the implementation, or about how various WP blogs are suggesting post types be implemented. Primarily, isn’t functions.php the worst place to set up post types, since register_post_types also affects the GUI of wp-admin – which is never usually theme-related? If one sets up post types within a theme-specific file that also happens to be subject to fairly frequent changes and improvements during build and once a site is live, aren’t there several big risks? Namely:

1) you could register a new custom post_type, start inserting posts, and then (you, a co-worker, a hacker, an ftp error) could willingly or inadvertently change functions.php and change the definition of the post_type (which, being a theme file not core wp-admin, wouldn’t run checks/validation of the definition against the database) leaving all the posts already entered either orphaned or broken, and the database cluttered with irretrievable junk.

2) your register_post_type function will get called at every page load: isn’t that wasteful at best, risky at worst?

3) you (or your client) could switch theme and, in doing so, lose the custom post_types – not just their display, but their admin too. It’s one thing to need to re-jig a theme to display them properly, but surely quite another to have to redefine their structure?

Although you mention in the article that register_post_types could be called from a plug-in, this also seems contradictory for such a deep-rooted new feature: we can imagine lots of competing plug-ins emerging, some with checks and balances, some without; some with neat admin GUIs, some without. Maybe that’s a benefit – natural selection will ensure the best plug-in emerges eventually – but in the meantime, WP support risks being flooded with desperate cries for help.

People often mention drupal and the CCK module… the point with that seems to be that the development path happened the other way round to WP and custom post types: CCK was developed (and evolved) as an external module for adding custom node types. It was only taken into drupal core once it (and its administration and security models?) were judged mature, stable and useful enough. With WP, what appears to be happening is the opposite: a core feature is added, but apparently without a good wp-admin section or data security features, and its implementation is being left up to non-core plug-in developers and, even worse, themers like me.

Doesn’t this risk making implementation of the new custom post types feature patchy and buggy, reducing WP’s perceived simplicity and strength? Custom post types seem to us to be so important that their registration and management should be in core wp-admin just as most of the best new features of recent releases have been.

Our understanding of the way post_types will work may be flawed or incomplete, in which case we’d LOVE to be reassured/corrected, because we really can’t wait to use them and feel that they’ll make WP an even stronger system for even more flexible sites. But we’re a bit worried at the moment.

I have been looking around the database and found that custom post types are implemented very cleverly. First of all, it is not really going deep rooted, its just an attribute in wp_posts table, all the magic is done on php level and everything is based on (imho) already perfectly working post/page post types. I believe they have been already making code level changes for custom post type to be possible for a long time (like unifying the editor page for posts and pages).

My 2Cs;

1-) functions.php is one of the right places to make the registration, custom post types can be seen as a feature of the theme.
2-) all logic regarding finding and displaying custom posts created when the theme is loaded. Therefore WP_Query and co is aware of the new custom post type after register_post_type() has run. There is no database query to ‘discover’ their presence. I find this effective, fast and flexible.

The major functionality I was waiting from WP 3.0 was Custom Post types. But I still don’t see how to determine exact custom fields for custom type.
I mean: we create movies database and create custom field “Actor”. Is there a way to only show this custom field when editing custom post type “Movies”? Because when I create a usual post I see “Actor” in custom fields and so on…

Curious about how to do certain things:
* Create an archives page (both a list and a search result page).
* Create sidebar navigation that lists “categories” and recent “posts” from custom post types.
I wanted to create a section on my site that would allow me to post different articles, and while I can do work-arounds for some things, I’d rather have a cleaner, easier, and much more organized way of doing things before I implement some of my ideas.
Any way I can achieve those things without to edit a thousand files or create an additional plugin to use?

This was a good article and proceeds with a good discussion. I am fairly new to PHP programming. I’ve created a custom post type fine and added some meta boxes. I have some questions with regards to creating a meta box for uploading images.

My custom post type is “Case Studies” which I have the editor registered to show a description for what the project was about. I have a custom meta box for showing the “Services Provided” (which is just a check box group). The final thing I want to be able to do is create some sort of image uploader. For each “Case Study” I want to display images. I would like to use some javascript on the presentation part to display these images.

Magic Forms was mentioned earlier about easily adding images but I want to stay away from using plugins if at all possible.

Do you have any suggestions or could you point me in the right direction? Thanks!

I have really been thinking about custom post types as a great way to have a simple forum that uses the standard WP database tables. I even started hacking some stuff in WP2.9, but decided to wait for 3.0. So I’m VERY interested in your work on a forum “plugin”. Your screenshot you posted looks absolutely perfect as I was thinking of modeling the look and feel like bbPress as well.

Since it sounds like you are looking for suggestions, I have a couple of key suggestions that wouldn’t naturally be available with just the WP3.0 custom post types:

1) I would like to a *separate* RSS feed for forum posts. Every discussion forum in the world has this, but this isn’t standard functionality with custom post types. In fact, it appears custom post types were designed to be used more like custom *pages* in that they get a permalink and it can be specified that they are searchable, but they do not appear in any RSS feed format.

2) Having run various forums over the years, it seems that most website owners would like to be able to easily specify that their “news” (“blog”) type posts get placed into the forums. Historically, people are more willing to comment on a forum than on an actual “news” article. At least that has been my experience with hobbyist type sites. I know this isn’t a problem for Engadget or CNN, but I think for smaller websites it could help increase the number of comments.

But if the forums are custom post types, then I don’t believe that we can simply flag a “blog” post to appear there, right? This would be easier if the forums were simply blog posts (and their comments) within a standard category taxonomy. i.e. I flag the article in its normal category and also tick off what forum category it should appear in. Notice no duplication of data and comments on the forums will appear on the blog article as well.

So with the combination of these two requirements (RSS feed and ability to post to the “blog” and “forums” at the same time), would it be better to have forums that are just normal blog posts and use the built-in category taxonomy or create a custom “forum” taxonomy? With that method, you’d have to filter your main RSS feed to exclude the posts that are *only* in the forum (but show them in the “forum” RSS feed). With custom post types you’d have to build your own RSS feed for the forums (I assume) and that sounds harder than simply hiding some posts from the main RSS feed.

Hi Justin, firstly thanks for the article and all the other awesome stuff you do.

I’ve been trying to figure out the best way to create a relationship between two or more custom post types but haven’t really been able to come up with a good and practical way of creating a direct relationship either as a 1-n or n-n relationship.

Merchants can have multiple special offers however a special offer can only have on merchant.

Brands can be associated with multiple merchants and a merchant can sell multiple brands. Brands may sometimes be associated with special offers and a special offer may apply to multiple brands.

So far the solutions I’ve come up with seem to require having duplicate entries for entities e.g. merchants as both a taxonomy or custom field and as a custom post type.

So far the solution I’ve come up with involves create a custom taxonomy containing merchant names, add that custom taxonomy to both the merchant custom post type and any other custom post type that needs to be associated with that merchant.

Is there a better way of doing this? E.g. the ability to load the titles of all posts within a single custom post type into a dropdown select box or list of checkboxes in the create interface for another custom post type?

I just want to make sure that there isn’t a cleaner, more direct or more obvious way of doing this that I’m not seeing before I commit to the custom taxonomy solution.

I’ve got DESTINATIONS and TOURS, and have struggled to find an easy way to link the two (both ways), apart from creating custom taxonomies of the same (Destinations and Tours)… and then it starts getting messy – especially if a client has to add a new post AND taxonomy for a new tour…

Yes! is there any way to load a list of all posts within a custom posts type?

Is there a better way of doing this? E.g. the ability to load the titles of all posts within a single custom post type into a dropdown select box or list of checkboxes in the create interface for another custom post type?

This comment asked how I could use custom posts in Wp 3.0 when released for a mortgage comparison site I am planning.
Here is the question and the variations possible for a home loan in Australia.

“How would I best use custom posts and taxonomies on this site? [Why did you elect to go for non hierarchal taxonomies.]
Most people only focus on interest rates.
Loans however could be classified by, Funder, loan size, down payment, lender, lender type, distribution channel/s, loan type, client type/ employment stability, income and job type/ partners/ downpayment, mortgage insurance [variable on deposit amount] loan purpose, loan costs, Property security, loan size, Interest fixed or variable or combo/ revolving credit line, Repayment options, Loan style, Loan options, Interest rates, Introductory discount offers, Loan terms, Loan conditions, Early repayment options, application fees, establishment fees, ongoing fees and charges, deferred fees, early repayment penalties, default fees and interest rates, default processes, Loan documention type, Credit rating/history/ scores. etc.
E.g. Client type could be first home buyer, self employed, with less than two years income/tax statements, with minor credit defaults. In Australia he would be paying a higher interest rate than a professional, such as an employed lawyer on $150,000 with clear credit, and be precluded from applying with many lender types [and or loan types]. Incomes, dependents and financial commitments can also affect the loan offered.
Each one of these can have a multiple choices, and or be dependent on other areas.”
Any suggestions would be appreciated.

How do I get the custom post type of the post to show up in the loop? I’ve created a few custom types, and I’d like the type to appear in a dialogue balloon over the thumbnail, so that visitors know they’re getting for example, a Video or a Photo. Cheers!

My hat is off to you Justin. This is one heck of a detailed tutorial 🙂

One of the custom post types I can see myself making is an event listing/information post type. I made a plugin called Advanced Events Registration (http://shoultes.net/wordpress-events-registration-with-paypal-ipn/) for WordPress that allows blog owners to publish events (including registration forms) to their blog. I also offer a free version, but the pro version of the plugin is actually a full event management suite which also allows you to create a post at the time of event creation. At the moment the new post is created by including a “post template” and a little bit of ob_start() and ob_end_clean() magic.

I am going to see if I can integrate what you have posted here. This looks like it may be a very promising alternative to what I am currently doing with ob_start() and ob_end_clean().

Any easy to understand guides on how to add options to the custom posts? For example, if a movie is drama, comedy, horror…. to have those options as check boxes WITHIN the custom post edit panel? I can’t seem to find a guide or plug-in for that.

It is a good idea to plot the data so that you can explore its features.
An exploratory plot of your data enables you to identify discontinuities
and potential outliers, as well as the regions of interest.
Thanks…

For those of you asking about / lamenting the lack of custom post type “archives” support (an equivalent to the blog home for a custom post type), I’ve put together a plug-in that plugs that hole in 3.0.

I’d be very grateful if you could add a few lines to your tutorial showing how to create a new role and give it the custom post type capabilities. Try as I might I can’t get it to work. In fact, including the capability_type argument WITHOUT a role ‘breaks’ the admin page, simply showing tags.

A role is definitely needed to make the capability_type argument work.

But if you have set your custom post type to be hierarchical, shouldn’t you be able to specify custom templates on a per-post basis just as you are able to for pages?

No. Custom post types (even hierarchical ones) are not pages. They are custom types of content. While WordPress does offer some basic publishing features, you (you, me, and other devs) are responsible for extending them.

Page templates are for pages. If you want to use custom templates though, you can definitely use them. My Hybrid theme will allow you to do this. Actually, Hybrid users have had this capability for six months now.

In the documenation for register_post_type the description of the “supports” attribute seems to imply that adding support for page-attributes will allow you to specify a custom template.

It’s a community Wiki. Not all information is 100% accurate. If you have a moment, please update it.

Well, that took some thinking through, but I figured out why I couldn’t get this sidebar block to show up.

First, I needed to scroll down in the WP Codex a bit more to find is_singular and how it mentions [blockquote]True when viewing a post of the Custom Post Types book. Introduced with Version 3.0.[/blockquote]

Then it was just a matter of making sure my other conditional statements above it that use is_single weren’t conflicting. 🙂

Just wanted to say thanks for a clear and easy-to-follow explanation of how to use custom posts. It’s rare for a beginner like me to be able to follow someone else’s instructions without misunderstanding.

hi i have also face same problem . how we can add sticky post featured in our custom post type. please help me . i am making a project , in which sticky post featured is essential in custom post type ” review “. please help me

For those who are having 404 error with custom post type, simply flushing the rewrite table upon activation sometimes doesn’t work. You have to first register the post type then flush the rewrite table in the activation hook.

I had the rewrite in the activation but it wasn’t working so I moved it to after the register_post_type and that worked but I seem to recall that the flush_rewrite_rules is pretty intensive and having it run every time the register function ran seemed silly.

having the register_post_type function run before doing the flush_rewrite_rules in my activation function did the job.

Using query, I can show up to 10 posts on page. But what about the pagination?

ie, I have custom post type called “Services”, I have 20+ services.

So specific service url is site.com/services/service-name01
Ten services will show on site.com/services (I’ve put that code in services.php and used it as page theme by creating a page called services)
Now I want to show rest of services on site.com/services/page/2 Any way?

If we include the post types in the functions theme, then this will be inherited to the network sites. This means that if I want to have a site where everybody can create their own Super Dupers listings, then all I have to do is make available themes that have that custom post type.

How does this work with POD? Can I make every user in the network use that post type?

Justin do you think you could write up a post on how to properly implement your custom post types to display the data with the title? So a Podcast would have length and speaker listed as categories and those options, when checked, would be displayed within the top view of the Podcasts in wordpress.

I know its fairly simple but it may be helpful and compliments your above code.

Wonder if you could shed your expert light on this one…I’ve created a hierarchical custom post type called Events, with the intention that any given event (eg Acme Conference 2010) will have several child posts (eg Agenda, Location, Bookings etc).

However, I can’t work out how to output a list of all the child posts of Acme Conference 2010. The WordPress Codex suggests that they’ve ‘added custom hierarchical post type support to get_pages() ‘, but has anyone had any success in listing out child posts from a hierarchical custom post type?

BUT if you had another custom post type with linked to the same taxonomy THEY would show up as well. I managed to get around this by, on the custom post type template (eg: product.php), to only display posts of a certain custom post type:

I can’t believe that I only just came across this post. This is exactly the kind of thing that would have just cut my custom post type learning curve in half! Thanks anyway for creating a great resource…

“One thing I would warn against is trying to separate your blog posts in this way. You have categories, tags, and custom taxonomies at your disposal if you’re just looking for a way to label them.”

Justin – Can you elaborate on what you mean by this? Are referring to styling your posts different as something to stay away from with custom post types, and using your existing category, tag taxonomies instead to do so?

hi Justin, this is quite useful thanks!
one question which i could not find elsewhere: if custom post types are making wordpress more like a cms and different tamplates can be aplied to different posts, is it possible to have more than one ‘editor’ box which is then rendered in particular divs in the actual theme? (i.e. more like a template skeleton, with editing boxes as a way to edit the content only in particualr sections)

Great Tutorial :), Just one small issue, I was getting stuck using the is_post_type() function with an error like this: “Call to undefined function is_post_type() in …” on the release version of WP3, and after some searching found that it has been renamed to “post_type_exists()” – Just a heads up to others who might be suffering the same fate :).

Thank you very much for putting all theses information together ! Just a question, can we have template and custom field for taxonomy ? Lets say I have a custom post type ‘MOVIE’ and I want to create a custom taxonomy ‘ACTOR’, can I put custom field to actor, like name, photo, year of birth,….

I’m really looking forward to the tutorial on combining custom posts and taxonomies, like it appears you did in your movie and book review demos. I just can’t seem to find a good source that explains this.

I really like custom post types, as it makes it way easier for clients to understand what’s happening (opposed to using custom fields!). I had a lot of trouble getting the “tags.php” page to work after getting custom post types up and running but found a fix. http://andrewroycarter.com/wordpress-2/wordpress-custom-post-types-tags-not-working/ It’s more of a workaround, so I’m really interested to see if there’s a better solution…

A small detail I noticed is that even though you can set a custom icon for your Custom Post Type to display in the sidebar menu, the default “thumbtack” icon displays when you navigate to the post edit page or the post listing page.

Like I said, a small detail, but I’m a sucker for consistency. Anyone know of a way to address this?

I am hoping someone can help me with this, I have created my custom post type, and registered a taxonomy. The custom page is displaying a list of posts, and archive is working, however the links through to individual posts are not. Here is my code from my functions file: http://pastie.org/1318089, and from within my page: http://pastie.org/1318095

hi justin,
i’m trying to add the ‘custom-fields’ option to the ‘support’ parameter in a custom post type, but somehow this options doesnt want to show up. I’ve tried all the other ones, like ‘author’, ‘excerpt’… they all do show up in the admin, but ‘custom-fields’ wont.

Have you ever seen this before?

I already used custom post types in a few wp projects and i’ve never come into this problem.

Nice work, but I am left wondering about the php code that you use to register the custom post type and why it differs from what’s used in the Codex. Perhaps you can explain?

In the codex page they have a $labels array and a $args array. Plus there are other inconsistencies. For example, when listing the labels, they have a ‘_X’ while you use a ‘__’. Can you clarify these differences for a PHP and WP newbie?

Yes and no. If you’re just looking to have a post type that behaves much like a blog post or page and would like to use only the basic arguments, it’ll probably have all the functionality you need. With anything more advanced, you’re better off just coding it yourself.

Custom post types are about implementation, not the default set of arguments provided through register_post_type(). It’s nearly impossible for a plugin to provide a UI to handle that.

The after_theme_setup hook is fired on every page load, just like the init hook. Your post type registration function must be executed on every page load; otherwise, it won’t work. init is the appropriate hook though.

I’m having a discussion with some folks on WordPress LinkedIn group who want to have two blogs in one site. They want to use a Custom Post Type for the second blog, and put the post type of Blog2 in the nav menu and return all posts in the second blog there, instead of setting up a network.

When Andrew Nacin gave his presentations at WordCamp NYC and Wordpress Raleigh, I believe he said that you don’t really want to use CPT for blogging, as that’s what the post type of Posts is for. And, that CPT is better suited for building data rich posts, like your example of a movie database.

Is it not recommended to use a CPT for Blog2, since you already have a post type called “post,” in the system? Is there a reason not to use it for a second blog on the same site?

For instance, create a Blog2 category. In the main blog loop, you would list all posts except posts with category Blog2. Then, in the Blog2 loop, you would filter for posts that ONLY have Blog2 as a category.

The same thing could be done with the RSS feed to keep the two “blogs” from crossing paths there.

This certainly appears evident in the beginning to separate in completely different post type, however I am as well attempting to comprehend what in addition will I have to do to use them. A couple of things aren’t crystal clear with me at this point, but I have one question. Sharing tags, I made a tag scheme just for this fresh post type, however it isn’t distributed along with pages and posts. Thus far I’ve discovered you can share a different scheme with various post types, however is it possible to share these tags too with different categories as well?

I have not yet coded something with custom post types, i’m currently reading and trying to figure out how give the blogs users a interface on the front end to insert new posts or edit their own’s.
There is no literature about how to get a working front end with custom post types, or at lease i’ve not found it anywhere in english nor spanish.

Please could you give us some light about that, or how do you implement it?

Thank you very much for all your efforts to continue always giving us valuous information!

I am trying to recreate an html site into Wordpress and I need to keep the exact URLs.
I used html on pages plugin and it worked just fine with pages.

For custom post types, I used Custom Post Permalinks plugin to give them a .html extension, but I keep getting 404 Not found errors.
I tried to follow your advise by visiting the Permalinks page, which used to work at first but not anymore.

I found a lot of articles dealing with custom posts, but this one is the mother of all custom post articles.

I have one final (hopefully) issue I’m not sure how to deal with. I can hack the custom post single template to fix, but hoping there is an easier fix in the functions file:

When I get to the individual news item (single-news.php), “News/Events” in navigation is not identified as the ‘current_page_parent’. Instead, the blog navigation item carries that class. Is there a quick way to make the class appear on “News/Events”?

I have found many examples of how to register the custom post type but almost nothing for best practices on how to show the custom post type, even more specifically how to show custom post type from a plugin with out changing or adding to a theme.

I have an example of a plugin that I found that does what I want to learn how to do. Below is the link to a events plugin that does not require you to add anything to your theme though it can show the custom post type just as if it was a custom template in your theme.

The plugin registers the custom post type “events” and then “with out adding any files to the theme folder” shows the custom post type “events” in a loop the when you go to the events slug url and also shows the event single post too. All the while never once needing to add anything to your theme folder making it the best way to use Custom Post types in a plugin which are not dependent on modifying your theme to work.

I like this approach since if I was to make a plugin that used custom posts I would not want the end user to have to upload or move files to their theme folder. I would want the plugin to show the content by inheriting the header and footer of the current theme and injecting my content into the loop or content.

The question in short is “how do I show the custom post type content from a template that lives in a plugin folder?”

I have seen use of hooks and filters like template_include and the_content but there is really no good tutorial for that. I think if there was a tutorial that would help most people who are trying to show their custom post type content since it falls into a common use with plugins more then with themes. Plus even with themes showing the content is just about the hardest part for most people regardless.

Really great article. I’ve created 2 custom post types with their own meta data types for a client. Now I have run into a roadblock that I should have thought of. I installed All In One SEO Pack and it does not support my custom post types. Big problem. Does anyone know of some similar to All In One that supports custom post types? Maybe I will need to hack into All In One, or if nothing works, I’ll have to remove the custom post types and go back to regular posts with categories.

Hi Justin,
Great tutorial, thanks!
Is it possible to create a custom post that has more then 1 editor field, I am trying to build a guides blog and each guide has many steps, I want each step to be a “post” so in the admin page there should be many textarea inputs, from my understanding it is not possible and every custom post can have only one editor fields.
Thanks!

Wow once again an really comprehensive guide for the rest of us. I’ve been really enjoying CPT’s and as many having lots of frustrations with them in certain instances but all in all loving CPT’s.

So much so that I’ve even started using CPT’s for functions other than they’ve been intended which has caused a few developers who are Purists to criticize my use of CPT’s. Whatever

So wondering if anyone out there has managed to figure out how to hide CPT admin tabs from certain users, eg. anyone lower than admin level? I’ce added a custom post type to a few projects to add some site settings and only want admins to see the dashboard link.

I aint now plugin developer so usually have to hack my way around doing these kinds of things.

I have a list of regular posts in the category “News” and I’ve also created a custom post type for “Events.” I’d like to list let’s say the most recent 10 posts for each on the same page. I don’t want them to intermingle. Rather, I want first one list to display and the other to display below it. Can I use WP_Query for this with two loops?

Thanks for the excellent tutorial. Very helpful. There’s one thing I keep missing, though. I have created custom post types on a site and added various labels. I want to make the labels show up on the posts, but they don’t. How do I call the labels so that they appear along with the content?

Hi, i know this blog post is rather old but still a good introduction to CPT.

I have a question: I would like my Custom Post Types to bee full text feeds, with the whole content. This url of course works http://sitename.com/feed/?post_type=name, but I only get excerpts in the feed. Regardless of setting feeds to be full text in Panel Settings.

I know there is snippets for including the Custom Post Types feed to the main feed. But I want separate feeds to be full content feeds.

Justin…. Im going to kiss you in excitement!!
Your tip with “Help! I’m getting a 404!” and “The easiest way to fix this is to simply visit your Settings > Permalinks page.” Worked!!!!!!!!!!!!!!!!!
Love you! I have been trying to solve this issue for few days… If I ever meet you, Im taking you for a beer…:)

Excellent read. I’ve only recently got started using Wordpress and although overall it’s pretty simple to get the hang of, there’ll always be things like this which you learn on a continuous basis. Thanks.

Third your tutorial is nice in detail but its not for newbie like me..you haven’t describe step by step process how and where exactly we should put the code so its hard to get the result with it.. I am in need for some step by step guide and would really appreciate if you can do..

Read up on some helpful entries, there is an entry on trac on how we shouldn’t use ‘type’ as that’s a reserved term etc. But I am NOT using type. I was using ‘tag’ to register a tax for the post type, I even tried changing that. Still, the gallery doesn’t show up (it tells me the # of images etc, but doesn’t show the images, hence I can’t add images etc from the gallery).

I’m not a PHP geek or Developer but i could follow it pretty nice step by step.

Only one question..

Will it be possible to add a category option to the back-end of this Custom Post Type ?
If we could, i think i could make a better and easier to use CMS for a friend who has no idea about building websites and working with them. So WordPress will be very new to him and it will be his first time working at a CMS.

At this point i have made a 3 way layout for showing off blog-posts.
Aside, Standard and Gallery Post Formats. All 3 of those Post Formats have their own templates and unique layouts the only problem i face right now is that i can’t change the names of the Post Formats at the back-end. (admin -menu).
So Gallery will always stay named like Gallery but really this way of posting at my website is something else right now. It has nothing to do with a Gallery-view anymore thats why i would like to rename the Post Formats but WordPress will not let me do this.

Thats why i was thinking, what if i made 3 different Post Types all with his own unique website layout attached to them, and maybe remove the basic POST option from the back-end admin menu. ??

That would solve the problem and would make the back-end for this person even easier to use , because he can clearly see the name of the layout (the Post Type) at the menu and start posting at.

How do we define custom titles for a custom post type? I’m trying to create a custom wordpress title for all posts made under a custom post. Basically, its a version changelog for an application. I would like to only input the version number in the title field, and the output has to be standardized with a string accordingly.

My custom post type is ‘custom_version’ and the title output that I’m looking for is “Application has been updated to version “.

I’ve understood that this can be achieved using add_filter and I’ve tried playing with this code for days now, but I’m not really a PHP Pro so help is much appreciated 🙂 Here’s the code:

This tutorial really helped, thanks! I was wondering if it was possible to use a variable when passing arguments to WP_Query()? I’ve looked everywhere and asked in the Wordpress forum – to no avail. Here’s my code:

When I echo $myVPname I get what I expect but the function can’t seem to get the variable value passed. When I pass a string of the actual value it works – but this isn’t an option for me. Any thoughts? Thanks in advance!

great tutorial, but i have a query:
“Suppose I create a custom post type say Form which is composed of few textarea and i want only that to be filled (not title, editor). i.e I want a UI entirely different from default post type(in administrator panel). Can I do it using custom post type API or its different thing i need to know. ”
Please help. Thanks in advance!

Hi,
Justin I have created a new custom post type named ‘programs’
& my permalink has been set as /%postname%/
& I m getting url like localhost/wordpress/programs/english-course-marketing-sales/
but I want to remove the programs{%custom-post-type%} part,
IS that possible in anyway ?
& how can I delete a custom-post type & remove all its instance from my database ?

How can I get a list of registered taxonomies for a specific post type?

My need/idea is as follows. I want to target content (e.g. banner ads, related articles, a testimonial, etc., whatever) as tightly as possible. For example, if I’m displaying a post W and Taxonomy Y and Term Z , but different content for custom post type X and Taxonomy Y and Term Z.

I reckon I can build a UI to assign “flags” to each of those intersections. However, I do not want the UI to list intersection that can not exit. That is, if a taxonomy is not resisted to a particular post type then I don’t want to configure it.

I’ve been looking for an answer for a couple days now. I can get all taxonomies across all post types. I can get the taxonomies/terms assigned to a particular object (but WP wp_get_object_terms does not seem to differentiate between no term assigned to that taxonomy and the taxonomy not being registered for the object ).

What I can’t seem to get is which taxonomies are registered to each post type. Maybe I’m going to have to define those relationship manually? Really 🙁

I’m having problems with permalinks using subcategories in taxonomies.
Everything works perfectly until the moment I need to do a subcategory.
I use the plugin “Custom Post Permalink” just to create the permalinks.
But does not work with the subs, does anyone have an idea of ​​how to do this?
Thanks

It was easy to create a custom post type with your tutorial, thank you.

While I know how to add custom fields and post types, do you know of a simple way to offer image uploads for custom fields? I don’t want to use WordPress “Featured Image” or the other WordPress image upload to because they’re too trivial for my target users.

I have one thorny issue that I haven’t cracked yet which maybe you have – which is how to make the parent of my custom posts a regular page in my WordPress site.

I have a series of events which suit being classed as a custom post type. I want to have a custom post for each event but to make them children of a ‘normal’ WordPress page – called Events.

I’ve registered the custom post type with hierarchical set to true and capability_type of page. I’ve also included ‘page-attributes’ in my ‘supports’ array.

The events are entered using a form on the site which when submitted uses wp_insert_post to insert the event ‘post’. They are inserted with a ‘post_status’ of ‘draft’ so that I can review them before publishing them. At this point I am trying to set the ‘post_parent’ of the custom post to the ID of the Events page.

The event posts are inserted fine but the parent relationship is not apparently established. When viewing the event pages the parent ID is 0 – so the breadcrumb on the page makes no sense.

Hi, I have a problem, I hope you can help me.
For example, I don’t want add new custom post of permalink by %name%, just by %ID%. I had setting the Settings > Permalinks like “/archives/%post_id%”. but it’s useless.
Thanks

I was wrestling with this all night, could not figure out why it wasn’t working kept getting the “404 Error” after each go around and would go back and tweak the code… had an inkling I needed to flush something…

Then I Googled and found this page and your one piece of simple advice:

Help! I’m getting a 404!

“The easiest way to fix this is to simply visit your Settings > Permalinks page. You don’t have to save your permalinks but just visit the page. This will flush your rewrite rules.”

You might want to mention this earlier in the post (for people who freak out like me when they see this error)

I read this post and learned a lot but I am having some slight issues with something and hoping maybe you could help me. I need to request feedback from one of my customers on a blog before I publish it and I have never used the custom fields for this, there has always been a box with discussion or feedback options, but I need to get this blog approved. What is the value to put in the “draftfeedback_requests” custom field in order to make sure that my customer has a chance to review the blog before publishing? If you could email me with the answer that would be awesome and I really appreciate it.

Thanks Justin, very great and clear explanation about custom post types… I am at the moment experimenting with them. I would love if you could also write us about the ‘post formats’, which were introduced in wordpress 3.1. There seems to be some confusion on these…

hmmm a v nice tutorial man i like i was very afraid of writing custom post types……ur tutorial gives line by line description of it,,,,,,my seniors guide me but not in such details……so thanks budddy …and best of luck and well wishes for ur life

i’ve been search on google till i been here. I have a problem with my wp permalink structure, specially for “attachment”. there an image i upload to my article, and the image will shown in gallery page, so the permalink result is : domain.com/bla-bla-bla.html/attachment/image-1

So, my question is, how to remove the “attachment” word on permalink structure. Fyi, i’m using WP version 3.3.1.

I’m running into a perplexing problem and I hope you have a moment to help.

I wrote a plugin/widget that is best described as CMS Lite. In short I create a custom post type and then use a shortcode to insert content from the custom post content into a standard post/page.

For example, I can maintain a list of “Recommended Articles” in one of my my_custom_post_type rows and then shortcode that content into any post or page. If I update the entry in my_custom_post_type it then “updates” all the shortcodes. Makes sense, yes? It’s very handy. Tons of cool uses when you think about it.

The problem is that when I use a plugin (e.g., http://wordpress.org/extend/plugins/sociable/) that uses add_filter( ‘the_content’, ) the my_custom_post_type also get appended to by the plugin. For example, I get Sociable share icons on the main post (as desired) but also on my shortcoded inserted content which makes me unhappy.

Might you have a suggestion / recommendation on how to stop this?

Here’s a link to my plugin / widget if you’d like to have a look. Of course if you want to spit some WP knowledge at me about it, please feel free. I did buy your WP plugin book. Unfortunately, it didn’t come with any free time and I’ve been too busy to order some. Hopefully soon 😉

Great post! Thank you for sharing.
I”m an amateur in Wordpress. Could you please help me with displaying custom posts? You have mentioned that:
“WordPress will show the singular view of your custom post types without any extra work. Once you create a new post, you’ll be able to view it by clicking on the View Post link.”
I do that and I see an empty post. No title, no text, nothing. What might be the problem? I use WP 3.2.1. Thanks

In your post you say: “One thing I would warn against is trying to separate your blog posts in this way. You have categories, tags, and custom taxonomies at your disposal if you’re just looking for a way to label them.”

Does anyone know how to do EXACTLY that? This is what I have been searching the last 2 days trying to do.

Categories is not enough for me, I want to be able to file my posts exactly to my liking in different areas of my site, not just on the 1 page.

I’m trying to add a custom post to my blog and have set it up to use tags from posts (the default ones). The problem is that my custom posts won’t show up in the tag pages. I can’t find a solution to this, aay ideas?

Hi, I had a hard time triing to understand if a Custom Post Type could help me for what I’m looking for.
What I realized is that a Custom Post Type is not a Post, right ?

Could you just answer to this question, it is very important please :
my theme inserts shortcode generator in blog posts to do many things. I don’t want registered people to use it.
Can I create with Custom Post Type blog posts just like if I didn’t use this theme ?

Hi I’m using custom-post-types-ui to create CPT’s with custom fields in. When I use a taxonomy picker or tag cloud I can’t get the custom field stuff to show up, is this usual. I have read about custom post archives but am not sure if its something to do with this. Can anyone point me to some relevant information. Thanks

I since found that the question from my last posted comment is not possible, but I do have another question what is the CSS to target a template named single-movies.php that I’ve created for a CPT called movies – Thanks

Honestly, I recommend using a different theme. Themes should never register custom post types. It’s plugin territory. I’m not sure if I’d trust a “premium” theme author who adds this stuff to a theme for sell.

Well, this is exactly what I needed! If you’re a theme developer and you work directly with the customers, you’ll want to integrate this kind of functionality into the theme! This opens the door for a lot of possibilities! Thank you for your great tutorial Justin! You really offered me a solution!

Thanks for the advice! I integrate that directly into the customer’s theme because I don’t have access to the ‘plugins’ folder and the the guy that is hosting the website doesn’t allow plugins installed to WordPress (no permissions). It’s a weird situation and this saves me from a lot of troubles! So once again, thanks a lot!

Hi guys,
I just discovered this post and I was wondering if this is the way to do what I need. I’m trying to build a product catalog. Each product has different options that are common to all products. Example:

I have produced custom post types with custom templates and custom fields. I want to create a page to display my CPT’s. Im using a child theme of twenty eleven and have used the code below from the WP codex but I just get a blank page.

Ok, I’m facing a strange issue now. I can add new posts with my custom post and without any issues, but the problem is with my custom post taxonomy. Whenever I attempt to delete of my terms in my taxonomy, in this case Person, I get an error:

An unidentified error has occurred.

If I go back to my Person taxonomy page, I can see that the term is deleted correctly. But, why this error? Any ideas?

I also notice that when I try to add a new Person to my custom post, there aren’t any errors, but that new person is listed in my category/taxonomy list right away. I’m not sure what’s going on here, so any help is appreciated.

Ok. I figured this out. I separated all my custom post type and taxonomy code in a separate php file, and had a close “?>” at the end of file which shouldn’t have been there. After removing that, everything works fine.

Is there any reason it’s bad to use a plugin to register custom post types and taxonomies? Somebody said these didn’t get written to the right place and should only be used for mockups, not actual use, and that worried me, but I’d rather use the WCK plugins if they’re fine.

You mean use a custom post type plugin that gives you an admin interface for registering post types? I’d say they’re pretty useless. Custom post types are about implementation, not registration. There’s not much point in using a plugin for the registration part when you’ve got to write a lot of PHP code to actually implement the thing anyway.

But, yeah, I’d only use them for quick mock-ups, not because they’re “bad” though. It just doesn’t make sense to use them in any other way to me.

If all you’re doing is registering post types and not having to write custom code to implement them, then I’d argue that you’re missing the purpose of custom post types and might as well be using regular posts/pages.

No. I’m having to do a bunch of stuff to implement. I’m just totally new to PHP coding and anywhere I can shorten my work-time, I want to, especially because I can’t figure out which code is better between the different suggestions on how to register, with verbose public options being buggy, the code generator using verbose and a different markup than your tutorial, and few tutorials actually just showing a single post type with all the markup complete as an example.

I know eventually this will all be old hat to me, but right now, I’m new and trying not to transform myself completely into a programmer/designer. I just want a site that does what I want and for free.

Hello I am using a wordpress theme with a custom post “portfolio”.
I loved the layout so I put all my post in there instead of the usual blog post.
However, when I checked my sitemap, I realized that all my post in the custom post “portfolio” is not being treated as a page. I mean, they don’t appear on my sitemap.
Is there a particular settings that make it so?
thank you.

Lately, I’ve been finding circumstances where I need to have my coder change templates and codes in my self-hosted wordpress blog. Being of a different discipline, I can’t explain to my coder how I want things done. After reading this post I somehow got some idea of the coding behind WP, thanks and I’ll point my coder to this page as well. Keep up the good work!

The major functionality I was waiting from WP 3.0 was Custom Post types. But I still don’t see how to determine exact custom fields for custom type.
I mean: we create movies database and create custom field “Actor”. Is there a way to only show this custom field when editing custom post type “Movies”? Because when I create a usual post I see “Actor” in custom fields and so on…

I still don’t understand…. I’ve spent some days learning how to do that, an that…and that….. And still doesn’t work….

I want to make an Event Calendar… every post(event) should have title, description, date, hour, category and location…. I want my events to be sorted by date and then viewed by category(if any event exist)

Ex: when I click on a date from my calendar, this is what i want to see in a new page:

Header

Date

Cat1.
Cat1Event1
Cat1Event2

Cat3
Cat3Event1
Cat3Event2
Cat3Event3

Footer

And when I click to an event, I want to see full description with location

Can you help me with some link to some tutorials? Or some words? What should I use? What should I need to do?

is there any way to have a custom taxonomy checkboxes show up as part of the custom meta box in admin? i’ve made a custom meta box show up for apartment for rent listings. my taxonomy is for number of bedrooms. now i want a sidebar with links to 1-bedroom, 2-bedroom, etc. that works with categories. but when i add listings to the property site, i want to be able to enter all my particulars in one custom meta box — with address, price, image, etc.

Is this possible? – a developer built my site and used your custom post types for the classified ads section of the website. He included a ranking system depending on the number of images included. It looks great front end, but when I work with these custom posts backend, the main body of the advert (or post) appears, not in the usual post text field, but in a custom description box. There are 2 of these, one for ads (posts) without images and one with. The ads look great styled for the classified ads pages, but there are 2 issues which I’d like to resolve:-
Firstly, if you use the search box to find an advert, it brings up the advert title, but nothing else. Is there a way of getting the whole advert to appear?
Secondly, I have used the query post plugin to put the latest 3 ads on the homepage. But to display the text, I am copying and pasting the text from the custom description boxes into the ‘normal’ post field. I’d like that to be automatic if possible. Also, because of the styling, it doesn’t include the contact details.
It’s difficult to explain, but can anyone help? I can provide screenshots backend if that helps. Thanks

In the admin, on that page editor, I see the template that is being used (on the right side under Page Attributes/Template), but I cannot find where to edit, add or delete the fields and information of this “template”. It’s driving me nuts…

I would really appreciate any help! Where can I find this template/form?

This is a great tutorial and I’m very grateful for it. I think I will be using custom post types a lot in future WordPress sites. I’m hoping you have another tutorial or can point me in the right direction to answer my next question:

How can I connect the custom post types?

For example, I have teachers and classes. Each teacher has a bio and each class has a description. But, when editing a class or a teacher, I’d like to be able to connect the two. If I’m on the Edit Teacher page, can I get a checkbox list or other list of classes to assign to that teacher? I can’t imagine I’m the first to have this need. Any help would be GREATLY appreciated.

I should write a tutorial on it sometime, but the concept isn’t too complex. Basically, you just need to save the teacher ID as post meta for the class posts or vice-versa. You’d need a custom meta box to handle that on the edit class screen in the admin. I’ve done it a few times for various projects.

Hey Justin. Thank you so much for your comprehensive posts. Now I want to remove the parent slug in the permalink of a child post. The child post is of a different cpt than the parent post. So I get example.com/parentcpt/parent-post-name/child-post-name which results to a 404. Switching between permalink structures doesnt help either. Ive tried a number of plugins but they dont solve. Adding 'rewrite' => array('slug' => false, 'with_front' => false) in the register_post_type doesnt help.
Please give me a functions.php bullet once and for all.. 🙂

Hello Justin,
Thank you so much for your post. It was really eyeopening for me. What I am really missing is the capability of creating custom “categories” for the post type and display them on the permalink. I have changed my permalink structure as “/%category%/%postname%/” yet no luck.

Been reading a lot these last days… but could not get it fixed: Almost everything is working fine (local environment), just added pagination, pagination works, but on page 2, 3, 4, et cetera the meta title tag outputs… “page not found”… the site itself shows perfectly with a couple of posts as intended.

Great post. I have a question though – is there a way to have the custom post types show up as posts under the defined author. Right now I am seeing them as the correct author but they are not showing up in the user panel under said author.

I removed that link because it was not the correct method of doing that, and I didn’t want people thinking it was. Anyway, WordPress handles pagination out of the box now. It only didn’t do it for like one version.

I want to display product attributes of 2 different product category with the help of conditional tags. But the condition was not working

bibleplanet.in/?product=i-belong-to-jesus this is a single product page of ‘t-shirt’ product category bibleplanet.in/?product=jesus-3 this is also a single product page of other category but in both category will display the same fields names called “width, height, thickness, frame size” in case of t-shirt i want to display the field names like “large, medium, small ..etc” with the help of custom field suite plugin i implement all these things and i introduce this condition called <?php if(is_product('t-shirt'))
but condition was not working both if and else part have tables can u have any idea 🙂
This is my code:-

This article is the real best I’ve ever read on the Internet about everything related to Custom Post Types. Thank you so so much for such this deep explanation (and you said it was just nothing compared to what you’ve liked to explain!) about these secret WP elements and their possibilities :)) I’m starving for the rest of the articles, this is the first one I ended up in. Thanks!