WordPress how to create a Custom Post Type (CPT) programmatically in php

One of the most important developments of recent years in WordPress has been adding the ability to create our own Custom Post Types (CPT).

This allows us to duplicate and use the Post/Page interface for our own purposes ( we can also customise it to add extra fields using custom meta data).

A great example of this is Woocommerce that uses a Custom Post Type of Product for the managing (add/editing etc…) of products. In this blog post I’m going show you how to use this great feature.

Creating a Plugin with a new Custom Post Type (CPT)

I’m going to create a custom post type of Singers as in the screenshot above. I’ll set this up as a plugin so in /wp-content/plugins/singersplugin/ I created a file called plugin.php , in this file I need to register the Custom Post Type like so:

add_action('init', 'create_gb_singer_post_type'); /* MUST be called on the init action/callback (will not work properly if not called at right time/place */

function create_gb_singer_post_type() {

    $args = array(
        'labels' => array('name' => __('Singers'), 'singular_name' => __('Singer')),
        'public' => true, /* shows in admin on left menu etc */
        'has_archive' => true,
        'rewrite' => array('slug' => 'singer'), /* rewrite the url eg host/singer   becomes host/singers */        
    );

    register_post_type(/* prefix gb_ namespace to avoid conflicts */ 'gb_singer', $args);

}

Its that simple to create if you just want a custom post type interface very similar to the existing post/page interface. As you can see I’ve called my post type ‘gb_singer’ , its good to prefix your variable/function names with something as it helps avoid conflicts with WordPress and other plugins.

How to nicely deregister our Plugin

Its also good practice to unregister stuff in your plugin when a user deactivates your plugin so you can so something like this at the end of the plugin.php file:

function gb_unregister_singers() { // run on deactivation (however it doesn't seem to delete custom posts )
    unregister_post_type('gb_singer');
}

/*
 * Usage for a custom post type named 'movies':
 * unregister_post_type( 'movies' );
 *
 * Usage for the built in 'post' post type:
 * unregister_post_type( 'post', 'edit.php' );
 */

function unregister_post_type($post_type, $slug = '') {

    global $wp_post_types;

    if (isset($wp_post_types[$post_type])) {
        unset($wp_post_types[$post_type]);

        $slug = (!$slug ) ? 'edit.php?post_type=' . $post_type : $slug;
        remove_menu_page($slug);
    }
}

register_deactivation_hook(__FILE__, 'unregister_post_type');

I’m going to expand on this example in my next few blog posts so you can see how to :

  • add fields to a custom post type
  • how to save a taxonomy on a custom post
  • how to add a featured image to a custom post type
  • how to create a tag cloud of a taxonomy related to one custom post type object

Update you can see how todo the above in my post here.

So if your interested in those things, check back at my blog soon. As always the Codex contains some great information so check it out here http://codex.wordpress.org/Post_Types

Leave a Comment