How to create a new Custom Post Type in WordPress

¿Do you want to create a new custom post type in WordPress programmatically?

Creating a new post type in WordPress is very simple, you just need to add a piece of code in your functions.php file.

Custom post types in WordPress are really useful and easy to implement. So, to create a new post type in WordPress it is only necessary to add a piece of code in your functions.php file.

Let’s create a new custom post type!

For this example let’s assume that we are creating a fitness topic for a personal trainer, who is going to sell training plans. To fulfill this purpose we need WordPress to have a type of post called “exercises”, where each new entry will be called as the name of an exercise and in its content you can have the instructions for its correct execution, video tutorial and/or reference images.

<?php
if ( ! function_exists('post_type_exercises') ) {

    // Register Custom Post Type
    function post_type_exercises() {

        $labels = array(
            'name'                  => _x( 'Exercises', 'Post Type General Name', 'svp_exercises_theme' ),
            'singular_name'         => _x( 'Exercise', 'Post Type Singular Name', 'svp_exercises_theme' ),
            'menu_name'             => __( 'Exercises', 'svp_exercises_theme' ),
            'name_admin_bar'        => __( 'Exercises', 'svp_exercises_theme' ),
            'archives'              => __( 'Exercise Archives', 'svp_exercises_theme' ),
            'attributes'            => __( 'Exercise Attributes', 'svp_exercises_theme' ),
            'parent_item_colon'     => __( 'Parent Exercise:', 'svp_exercises_theme' ),
            'all_items'             => __( 'All Exercises', 'svp_exercises_theme' ),
            'add_new_item'          => __( 'Add New Exercise', 'svp_exercises_theme' ),
            'add_new'               => __( 'Add New', 'svp_exercises_theme' ),
            'new_item'              => __( 'New Exercise', 'svp_exercises_theme' ),
            'edit_item'             => __( 'Edit Exercise', 'svp_exercises_theme' ),
            'update_item'           => __( 'Update Exercise', 'svp_exercises_theme' ),
            'view_item'             => __( 'View Exercise', 'svp_exercises_theme' ),
            'view_items'            => __( 'View Exercises', 'svp_exercises_theme' ),
            'search_items'          => __( 'Search Exercise', 'svp_exercises_theme' ),
            'not_found'             => __( 'Not found', 'svp_exercises_theme' ),
            'not_found_in_trash'    => __( 'Not found in Trash', 'svp_exercises_theme' ),
            'featured_image'        => __( 'Featured Image', 'svp_exercises_theme' ),
            'set_featured_image'    => __( 'Set featured image', 'svp_exercises_theme' ),
            'remove_featured_image' => __( 'Remove featured image', 'svp_exercises_theme' ),
            'use_featured_image'    => __( 'Use as featured image', 'svp_exercises_theme' ),
            'insert_into_item'      => __( 'Insert into Exercise', 'svp_exercises_theme' ),
            'uploaded_to_this_item' => __( 'Uploaded to this Exercise', 'svp_exercises_theme' ),
            'items_list'            => __( 'Exercises list', 'svp_exercises_theme' ),
            'items_list_navigation' => __( 'Exercises list navigation', 'svp_exercises_theme' ),
            'filter_items_list'     => __( 'Filter Exercise list', 'svp_exercises_theme' ),
        );
        $args = array(
            'label'                 => __( 'Exercise', 'svp_exercises_theme' ),
            'description'           => __( 'Custom Post Type for exercises theme', 'svp_exercises_theme' ),
            'labels'                => $labels,
            'supports'              => array( 'title', 'editor', 'thumbnail', 'custom-fields' ),
            'taxonomies'            => array( 'category', 'post_tag' ),
            'hierarchical'          => false,
            'public'                => true,
            'show_ui'               => true,
            'show_in_menu'          => true,
            'menu_position'         => 5,
            'menu_icon'             => 'dashicons-heart',
            'show_in_admin_bar'     => true,
            'show_in_nav_menus'     => true,
            'can_export'            => true,
            'has_archive'           => true,
            'exclude_from_search'   => false,
            'publicly_queryable'    => true,
            'capability_type'       => 'post',
            'show_in_rest'          => false,
        );
        register_post_type( 'exercises_post_type', $args );

    }
    add_action( 'init', 'post_type_exercises', 0 );

}

Note: The above code has compatibility for child themes since it checks before the function does not exist.

Explanation

Steps:

  1. Create a function and add the action.

    In this example we create the function post_type_exercises() and we tell WordPress that we want that function to be executed at startup, for this reason we added the code “add_action( ‘init’, ‘post_type_exercises’, 0 );”

  2. Create an array of labels

    As you can see in the code, there is a variable $labels that contains an array of labels, this is in order to have a custom text inside the custom post type menu, as you can see in the next photo:
    Creating new custom post type using WordPress
    It is very important that if your theme or plugin is going to be available in several languages, you must internationalize the text labels and include the text_domain of it, in this example swe used the text_domain “svp_exercises_theme” and the titles are included in the translation fields _x and __ respectively

  3. Create an array of arguments

    These arguments are the ones that indicate to the function that registers a new post type, the characteristics that it will have, for example the labels that were created previously, the icon that it will have in the menu (in this case a heart, you can use all of these), permissions to be called in wp_query or to be displayed using the WordPress REST API, as well as categories and tags for posts

  4. Register the new post type

    In this step, only the register_post_type() function must be invoked, to which the slug of our new post type and its arguments are sent, like this: register_post_type( ‘exercises_post_type’, $args );

Final thoughts

With the previous steps we have already created a new custom post type, now if you need to know how to read its posts, I recommend you read my post about the WP_Query class where I explain how to do it.

https://cpp-dedicated.staging.mysites.io/