Using Custom Post Types in WordPress

WordPress released the Custom Post Types option in Version 3.0 and since then it has become a favorite for WordPress developers whenever a piece of content doesn’t fit neatly into the page or post  column. They are one of our favorite tools over here so I thought I’d take some time to fill you in on how and when to use CPT.


Sometimes you have content that simply doesn’t fit into an existing, prescribed content box. Sometimes you want to organize different types of content easier. With Custom Post Types, you can organize your content however you want, add as many individual custom content fields using Custom Metaboxes, and even create unique taxonomies. You can also query these posts types by themselves without pulling your blog posts or pages and therefore reducing your query times.

Basically, Custom Post Types give significantly more flexibility and options to both the developer and user.


We run into a variety of content that wouldn’t necessarily work very well if it were simply another page or post. For example, it’s relatively common to have interchangeable boxes on the home page to highlight different content. These boxes usually have an image, a small amount of text, a title, and a link to an internal page, and an ordering mechanism. The first three parts fit neatly into a normal page, but what about a URL and an ordering mechanism?

In addition, you’d have to have the end client go in and slosh through 20 – 100 pages to find one of their home page boxes – not ideal or efficient.

Screen Shot 2013-09-09 at 4.16.29 PMHow

Using Custom Posts may look intimidating, but they’re actually really easy. You basically go through and add the following code to your functions.php (or referrably a mu-plugin file with all of your non-theme functions).

[cc lang=”php”]

// ================ CUSTOM POST TYPE [PORTFOLIO]

function my_custom_post_portfolio() {
$labels = array(
‘name’ => _x( ‘Portfolio Item’, ‘post type general name’ ),
‘singular_name’ => _x( ‘Portfolio Item’, ‘post type singular name’ ),
‘add_new’ => _x( ‘Add New’, ‘book’ ),
‘add_new_item’ => __( ‘Add New Portfolio Item’ ),
‘edit_item’ => __( ‘Edit Portfolio Item’ ),
‘new_item’ => __( ‘New Portfolio Item’ ),
‘all_items’ => __( ‘All Portfolio Items’ ),
‘view_item’ => __( ‘View Portfolio Item’ ),
‘search_items’ => __( ‘Search Portfolio Items’ ),
‘not_found’ => __( ‘No portfolio items found’ ),
‘not_found_in_trash’ => __( ‘No portfolio items found in the Trash’ ),
‘parent_item_colon’ => ”,
‘menu_name’ => ‘Portfolio’
$args = array(
‘labels’ => $labels,
‘description’ => ‘Portfolio Items for the front page.’,
‘public’ => true,
‘menu_position’ => 5,
‘supports’ => array( ‘title’, ‘editor’, ‘thumbnail’, ‘excerpt’ ),
‘has_archive’ => true,
register_post_type( ‘portfolio’, $args );
add_action( ‘init’, ‘my_custom_post_portfolio’ );

function my_updated_messages_portfolio( $messagesportfolio ) {
global $post, $post_ID;
$messagesportfolio[‘portfolio’] = array(
0 => ”,
1 => sprintf( __(‘Portfolio Item updated. <a href=”%s”>View Portfolio Items</a>’), esc_url( get_permalink($post_ID) ) ),
2 => __(‘Custom field updated.’),
3 => __(‘Custom field deleted.’),
4 => __(‘Portfolio Item updated.’),
5 => isset($_GET[‘revision’]) ? sprintf( __(‘Portfolio Item restored to revision from %s’), wp_post_revision_title( (int) $_GET[‘revision’], false ) ) : false,
6 => sprintf( __(‘Portfolio Item published. <a href=”%s”>View Portfolio Item</a>’), esc_url( get_permalink($post_ID) ) ),
7 => __(‘Portfolio Item saved.’),
8 => sprintf( __(‘Portfolio Item submitted. <a target=”_blank” href=”%s”>Preview Portfolio Item</a>’), esc_url( add_query_arg( ‘preview’, ‘true’, get_permalink($post_ID) ) ) ),
9 => sprintf( __(‘Portfolio Item scheduled for: <strong>%1$s</strong>. <a target=”_blank” href=”%2$s”>Preview Portfolio Item</a>’), date_i18n( __( ‘M j, Y @ G:i’ ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
10 => sprintf( __(‘Portfolio Item draft updated. <a target=”_blank” href=”%s”>Preview portfolio item</a>’), esc_url( add_query_arg( ‘preview’, ‘true’, get_permalink($post_ID) ) ) ),
return $messagesportfolio;


Just go through the code, do a find and replace on “Portfolio Item” and portfolio and voila! You have your custom post type. Start using these and getting experience with them to level up your WordPress development!