Custom Post Types
WordPress introduced custom post types in WordPress 3.0. That seems not too long ago since we’re on version 4.3 now, but version 3.0 (dubbed Thelonious Monk) was back on June 17, 2010. So this feature has been around for over 5 years. The codex has a pretty decent post about it here. Read up a little if you need to get a little more familiar with it before continuing on to the “Getting Started with this Custom Post Type Tutorial” heading. You can also go here as well to learn about the function that registers your post type.
Getting Started with this Custom Post Type Tutorial
As always whenever you’re editing something that could potentially break your WordPress site, you’ll want to make a back-up of the file. I have read in many different places that it’s a good idea to put your custom post type registrations in a plugin, so that if you switch themes for whatever reason, you’ll still have access to all of your data. I might write a tutorial on how to do that a little later on.
For this custom post type tutorial we are going to assume you’re using functions.php
just make sure you, like I said, make a backup of it before continuing. You also might want to enable debug mode in your wp-config.php
as well. If you’re unfamiliar with that concept, just go to wp-config.php
, commonly in your root directory, and switch define('WP_DEBUG', false);
to define('WP_DEBUG', true);
and you’ll be set. Don’t do this if you’re in a production environment or if you are uncomfortable debugging PHP, because you might get an error message you won’t know what to do with (although you can always Google it). Error logs are also your best friend for debugging new features like this.
WordPress Post Type Labels
I’m going to just steal a page from the Codex to help explain what each of the labels are, because it does a pretty good job:
- ‘name’ – general name for the post type, usually plural. The same as, and overridden by $post_type_object->label
- ‘singular_name’ – name for one object of this post type. Defaults to value of ‘name’.
- ‘menu_name’ – the menu name text. This string is the name to give menu items. Defaults to a value of ‘name’.
- ‘name_admin_bar’ – name given for the “Add New” dropdown on admin bar. Defaults to ‘singular_name’ if it exists, ‘name’ otherwise.
- ‘all_items’ – the all items text used in the menu. Default is the value of ‘name’.
- ‘add_new’ – the add new text. The default is “Add New” for both hierarchical and non-hierarchical post types. When internationalizing this string, please use a gettext context matching your post type. Example:
_x('Add New', 'product');
- ‘add_new_item’ – the add new item text. Default is Add New Post/Add New Page
- ‘edit_item’ – the edit item text. In the UI, this label is used as the main header on the post’s editing panel. The default is “Edit Post” for non-hierarchical and “Edit Page” for hierarchical post types.
- ‘new_item’ – the new item text. Default is “New Post” for non-hierarchical and “New Page” for hierarchical post types.
- ‘view_item’ – the view item text. Default is View Post/View Page
- ‘search_items’ – the search items text. Default is Search Posts/Search Pages
- ‘not_found’ – the not found text. Default is No posts found/No pages found
- ‘not_found_in_trash’ – the not found in trash text. Default is No posts found in Trash/No pages found in Trash.
- ‘parent_item_colon’ – the parent text. This string is used only in hierarchical post types. Default is “Parent Page”.
There you have it, all the labels available to WordPress and what they mean. You might be asking yourself, “That’s great, but how do I implement that?” Well, scroll down to the next part of this lovely custom post type tutorial to find out.
“Robust” Example
<?php
function register_custom_post_types() {
/**
* REVIEWS POST TYPE
* @author Kevin Dench
*
* @uses This post type will be used to help with user feedback submissions
*
* @var $args the args include the exclusion from search, showing the post type in the admin bar when navigating the site for improved usability. This also
* has a parameter for WordPress feed.
* @var $labels naming conventions. Some seem redundant, however control over default WordPress naming for the admin bar is necessary through menu_name.
*
**/
$labels = array(
'name' => _('Reviews'),
'singular_name' => _('Review'),
'menu_name' => 'User Reviews',
'add_new_item' => 'Post a New Review',
'name_admin_bar' => 'Reviews',
'add_new' => 'Post a New Review',
'edit_item' => 'Edit this Review',
'new_item' => 'Publish a new Review',
'view_item' => 'View this Review',
'not_found' => 'No reviews found.',
'not_found_in_trash' => 'Review has been ignored.',
'parent_item_colon' => 'Review Parent',
'search_items' => 'Search all of your Reviews',
);
$args = array(
'labels' => $labels,
'description' => 'This post type will be used to help with user feedback submissions.',
'public' => true,
'exclude_from_search' => false, //Do not exclude from search
'menu_position' => 6,
'show_in_admin_bar' => true,
'menu_icon' => 'dashicons-clipboard',
'hierarchical' => true,
'taxonomies' => array('post_tag'),
'rewrite' => array('slug' => 'reviews', 'with_front' => false),
'supports' => array('title', 'author', 'revisions', 'excerpt', 'page-attributes')
);
register_post_type('reviews', $args);
}
add_action('init', 'register_custom_post_types');
?>
You will notice that I have some PHP commenting in there. This is pretty important stuff to include so you can remember not only where things are, but what the code is doing. This is especially vital in a collaborative development environment, good documentation of your functions and methods are very important.
Next I wanted to point out how we’re using the labels. We have set up an array of label options, and since the label key => value
pair is able to take an array as a value, this works well. In fact, you’ll notice that taxonomies
, rewrite
, and supports
also take an array, even if you only have one item in there.
Note the menu_icon
also known as a dashicon, where you can find the list of available WordPress icons here.
Wrapping Up
There you have it, it’s pretty self-explanatory, and you can get even more robust with your post types. I generally like to customize the “add new post” button label, as well as the trash message. I mainly like customizing the emptied trash message because I like including Easter Eggs.
What kinds of things are your go-to’s when registering post types? Did I leave anything out in my custom post type tutorial that you would like to add? Go ahead and leave these in the comments, and I’ll take a look!