How to create custom post type in WordPress
Home » BLOG » WordPress » How to create custom post type in WordPress

How to create custom post type in WordPress

category:  WordPress

How to create custom post type in WordPress? This is a popular question for WordPress. The custom post type extends the WordPress ability.

In WordPress, there are five default post type that used by the WordPress installation which are Post(post), Page(page), Attachment(attachment), Revision(revision) and Navigation menu(nav_menu_item). More detail you can read from here.

However, in some situations, you may need your own custom post type for storing your specific data such as project, researcher and more. There are two ways you can create the custom post type.

Create custom post type with your own plugin

I personally like to create the custom post type with my own plugin. This way, I can fix any issues by myself. And I can fix them faster. Sometime the free plugin or paid plugin have the issues and they will take time to fix them or the plugin developers won’t continue to develop their plugins anymore. Plus creating the custom post type without plugin is not difficult at all. Today I will share with you.

Note that, I recommend you to create the custom post type from your own plugin rather than the theme(functions.php). This way, when you change the current theme, the content stored in the custom post type won’t disappear.

Create your own plugin

Let’s say. We are going to create the new project post type. Below is the steps.

  • create a new project-cpt folder under the WordPress plugin folder (wp-content/plugins).
  • create a new project-cpt.php under the project-cpt folder. Notice that, we name the the main plugin file as project-cpt which is the same as our new folder name. It is a best practice following the WordPress Codex.
  • In this tutorial, we will create the plugin by using the class based. So in the project-cpt.php, we will include the new class file. The code is below.

 * Plugin Name: Project CPT
 * Description: Project Post Type
 * Version: 1.0
 * Author: Apple Rinquest
 * Author URI:

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.

// include our class files
require plugin_dir_path(__FILE__) . 'classes/class-register-project-post-type.php';
  • Next, we create a new classes folder under the project-cpt folder then we create the new class-register-project-post-type.php under the classes folder.
  • Now your plugin structure will look like this.
    • project-cpt folder
      • classes folder
        • class-register-project-post-type.php
      • project-cpt.php

Create a custom post type

  • In the class-register-project-post-type.php, we add the code below.
// we add this code to prevent people accesses the file directly.
defined('ABSPATH') or die('No script kiddies please!');

/* we check the exists class first to avoid the conflict with other plugins or theme. If MMS_Project_CPT class is never declared before, we will declare our MMS_Project_CPT class as below.
It is good for naming your class name with the unique name.
if (!class_exists('MMS_Project_CPT')) {

  class MMS_Project_CPT
     * start up
    public function __construct()
      // add new custom post type
      add_action('init', array($this, 'project_post_type'));

     * register new custom post type
    public function project_post_type()
      // note, custom post type name is maximum 20 characters.
          'labels' => array(
            'name' => __('Projects', 'mms-project-cpt'),
            'singular_name' => __('Project', 'mms-project-cpt'),
            'add_new' => __('Add New Project', 'mms-project-cpt'),
            'add_new_item' => __('Add New Project', 'mms-project-cpt'),
            'edit' => __('Edit', 'mms-project-cpt'),
            'edit_item' => __('Edit Project', 'mms-project-cpt'),
            'new_item' => __('New Project', 'mms-project-cpt'),
            'view' => __('View', 'mms-project-cpt'),
            'view_item' => __('View Project', 'mms-project-cpt'),
            'search_items' => __('Search Project', 'mms-project-cpt'),
            'not_found' => __('No Project found', 'mms-project-cpt'),
            'not_found_in_trash' => __('No Project found in Trash', 'mms-project-cpt'),
          'public' => true,
          'show_ui' => true,
          'menu_position' => 50,
          'rewrite' => array('slug' => __('projects', 'mms-project-cpt')),
          'menu_icon' => 'dashicons-carrot'
  // end of project_post_type

 // end of class

// initiate the class
$mms_project_ctp = new MMS_Project_CPT();

Basically, we register new custom post type with register_post_type function. You can change the arguments to fit your needs.

Now, you enable our plugin. After that, you should see the new project menu as shown below.

Custom Post Type
Figure: New Project Post Type Menu

When you click on “Add New Project” menu, you will see the adding form below. You will see the title and content editor which are the default fields in WordPress. You can remove the fields as you need by modifying the supports parameter.

Custom Post Type adding form
Figure: New Project Post Type adding form

And that’s how we create the custom post type with our plugin.

Create custom post type with plugin

If you don’t feel comfortable with coding by your self, you can use the free or paid plugins. I will use the Custom Post Type UI plugin for this tutorial.

Go ahead, download the Custom Post Type UI plugin and enable the plugin on your site.

Now, you will see the CPT UI menu as below.

Custom Post Type UI plugin
Figure: Custom Post Type UI menu

Click on “Add/Edit Post Types” menu for adding new custom post type. On the adding form, fill in all required fields and click on “Add Post Type” button for saving. That’s it. It is simple and easy way for non-coder.

With the CPT UI plugin, you can create the custom taxonomy for the post type as well. Plus, you can export and import the taxonomies and post types settings. And you can get the PHP code from the custom post types and custom taxonomies from the CPT UI plugin too. It is convenience.

And that’s it for today.