Create Custom Post Types in Wordpress

Wordpress stores its content as post types. Taken from wordpress official Post Types page every single item is called post which is also the default post type of wordpress. Wordpress allows you to create your own custom post types, We will create a custom post type "movies" in this post.

Create Custom Post Types in Wordpress
By default wordpress comes with the following post types unless removed by developer.
  • Posts: A default post type for all blog posts.
  • Pages: A post type for pages and can create hierarchical page structure.
  • Revisions: A special post type used to keep a history of other post types.
  • Attachments: Another special post type used to hold information about any media uploaded.
  • Menus: A post type used to create menu for navigation purposes on website.
  • Custom CSS: A theme specific post type to store css changes saved from customizer (Additional CSS).
  • Changesets: These post types are like revisions but to store history of changes made from customizer.

Custom Post Types

Wordpress allows to create your own custom post types as per your need for example you want to create a custom gallery or slider, you can create custom post types to store them as separate posts. Custom post types are created using "register_post_type" function. Lets create our custom post type for movies.
register_post_type("your_post_stype", $arguments);
The first parameter is your custom type slug and second parameter is an array of arguments for our custom post type or/and any other custom post types. We will create cpts.php file and place our custom post type registration code in this file. Next we will include this file in "functions.php".

cpts.php

<?php
function custom_cpts(){
    // --- Labels Array --- //
    
    // General name for the post type, usually plural
    $labels["name"] =  __( "Movies", "textdomain");
    
    // Name for one object of this post type
    $labels["singular_name"] = __( "movie", "textdomain");
    
    // Label to signify all items in a submenu link
    $labels["all_items"]     = __( "All Movies", "textdomain");
    
    // Label for adding a new singular item button on list screen
    $labels["add_new"]       = __( "Add Movie", "textdomain");
    
    // Label for adding a new singular item
    $labels["add_new_item"]  = __( "Add New Movie", "textdomain");
    
    // Label for editing a singular item
    $labels["edit_item"]     = __( "Edit Movie", "textdomain");
    
    // Label for the new item page title
    $labels["new_item"]      = __( "New Movie", "textdomain");
    
    // Label for viewing a singular item
    $labels["view_item"]     = __( "View Movie", "textdomain");
    
    // Label for viewing post type archives
    $labels["view_items"]    = __( "View Movies", "textdomain");
    
    //Label for searching plural items
    $labels["search_items"]  = __( "Search Movie", "textdomain");
    
    //When no movies is found in admin screen
    $labels["search_items"]  = __( "No Movies Found", "textdomain");

    //--- Custom Post Type Arguments ---//
    
    // Name of the post type shown in the menu.
    $cpt_args["label"]  = __( "Movies" );
    $cpt_args["labels"] = $labels;
    
    // Whether a post type is intended for use publicly
    $cpt_args["public"] = true; 
    
    // The url to the icon to be used for this menu
    $cpt_args["menu_icon"]  = "dashicons-format-video"; 
    
    // Whether to generate and allow a UI for managing this post type in the admin
    $cpt_args["show_ui"] = true; 
    
    // Whether to delete posts of this type when deleting a user
    $cpt_args["delete_with_user"] = false; 
    
    // Where to show the post type in the admin menu
    $cpt_args["show_in_menu"] = true; 
    
    // Makes this post type available for selection in navigation menus
    $cpt_args["show_in_nav_menus"] = true; 
    
    // Whether to exclude posts with this post type from front end search results
    $cpt_args["exclude_from_search"] = false; 
    
    // Whether the post type is hierarchical
    $cpt_args["hierarchical"] = false; 
    
    // Sets the query_var key for this post type
    $cpt_args["query_var"] = true; 
    
    // Core feature(s) the post type supports
    $cpt_args["supports"] = ["title", "editor", "thumbnail","comments"]; 

    register_post_type( "movie" , $cpt_args );
}
// Register Post Type on init Hook
add_action( "init", "custom_cpts" );
?>