Home / Tutorials / Create Custom Post Type in WordPress Manually

Create Custom Post Type in WordPress Manually


Custom post types are helpful when it comes to separating and organising different types of content.
It is similar to regular post types but with different post_type value in the database. In this tutorial we will learn how to create custom post type in WordPress.

WordPress comes with five built in post types:

  • post
  • page
  • Attachment (media files)
  • revision
  • Navigation menu

This feature to create custom post type has extended the capability of WordPress beyond the blogging platform into a powerful Content Managed System.

You can create the custom post type either with the help of plugins or you can achieve it the custom way.
I would prefer the later one, it is because the plugins are bulky and comes with many features that might not be necessary for your project and can effect the performance of your website.

However, if you would like to create the custom post type from plugin you can use Custom Post Type UI which is free and is available in the WordPress plugins repository.

Now lets get started with creating the custom post type manually:

Create Custom Post Type in WordPress:

The ideal way of creating custom post types would be by creating a plugin and registering custom post types in your plugin. However, you can also register the custom post types in your theme file, functions.php.

Chances are you might change the theme and the custom post type will disappear. All the posts and related information will still be there in the database but you cannot access it from the admin end.

The following minimal snippet registers the custom post type tutorials.

function create_custom_post_type() {
    register_post_type('tutorials', //custom post type key
            'labels'      => array(
                'name'          => __('Tutorials', 'wpatlas'),
                'singular_name' => __('Tutorial', 'wpatlas'),
                'public'      => true,
		'has_archive' => true, //true for enabling archive page
		'rewrite' => array('slug' => 'tutorials') //specify your desired slug. Default will be the post type key
                'show_in_rest' => true, //true for enabling block editor(gutenberg), false will enable the normal editor
add_action('init', 'create_custom_post_type');

Note: Call register_post_type after after_setup_theme and before admin_init. The ideal hook to use is init. Make sure the custom post type key doesn’t conflict with the other existing post type.

The above snippet will get you started with the creating custom post types. But you might need more features enabled such as taxonomy, custom fields, excerpt, featured image and many more. The example below registers Custom Post Type and enables additional features.

function create_custom_post_type() {
    // Labels names for Custom Post Type
	$labels = array(
		'name'                => __( 'Tutorials', 'wpatlas' ),
		'singular_name'       => __( 'Tutorial', 'wpatlas' ),
		'menu_name'           => __( 'Tutorials', 'wpatlas' ),
		'parent_item_colon'   => __( 'Parent Tutorial', 'wpatlas' ),
		'all_items'           => __( 'All Tutorials', 'wpatlas' ),
		'view_item'           => __( 'View Tutorial', 'wpatlas' ),
		'add_new_item'        => __( 'Add New Tutorial', 'wpatlas' ),
		'add_new'             => __( 'Add New', 'wpatlas' ),
		'edit_item'           => __( 'Edit Tutorial', 'wpatlas' ),
		'update_item'         => __( 'Update Tutorial', 'wpatlas' ),
		'search_items'        => __( 'Search Tutorial', 'wpatlas' ),
		'not_found'           => __( 'Not Found', 'wpatlas' ),
		'not_found_in_trash'  => __( 'Not found in Trash', 'wpatlas' ),
    // Arguments for registering custom post type
    $args = array(
		'labels'              => $labels,
		// define the features that you need in your post
		'supports'            => array( 'title', 
		'hierarchical'        => true, // enables child posts, set to false if parent child relationship is not required
		'public'              => true,
		'show_ui'             => true,
		'show_in_menu'        => true,
		'show_in_nav_menus'   => true,
		'show_in_admin_bar'   => true,
		'menu_position'       => 3,
		'can_export'          => true,
		'has_archive'         => true,
		'exclude_from_search' => false,
		'publicly_queryable'  => true,
		'capability_type'     => 'post',
        'rewrite' => array('slug' => 'tutorials'), //specify your desired slug. Default will be the post type key
		'show_in_rest' => true,
	register_post_type( 'tutorials', $args );
	// register custom taxonomy (categories)
	// hierarchical => true creates category features
	// hierarchical => true creates tag features
	register_taxonomy('tutorial_category', 'tutorials', array('hierarchical' => true, 'label' => 'Tutorial Category', 'show_in_rest' => true, 'rewrite' => array( 'slug' => 'tutorial-category' )));
	//registers custom taxonomy (tags)
    register_taxonomy('tutorial_tag', 'tutorials', array('hierarchical' => false, 'label' => 'Tutorial tags', 'show_in_rest' => true, 'rewrite' => array( 'slug' => 'tutorial-tag' )));
add_action( 'init', 'create_custom_post_type' );

That’s it! This is how you register a custom post type in WordPress. You can now find the Tutorials custom post type in admin end with Tutorial Category and Tutorial tags. Now start adding your contents in a separate custom post type.

Join 17,000 others who receive our weekly email newsletter.