How to create custom post types in WordPress: Complete and Advanced Guide

Custom Post Types (CPTs) are a powerful way to extend WordPress beyond pages and posts. With them, you can organize custom content like portfolios, events, or products, offering solutions tailored to your needs. In this article, we’ll explore how to create them using  register_post_type() and make the most of its advanced options.

Basic creation of a custom post type

The following code creates a basic CPT called “Books”:

<?php
function registerBookPostType() {
    $args = [
        'label'     => 'Books',
        'public'    => true,
        'supports'  => ['title', 'editor', 'thumbnail'],
    ];
    register_post_type('book', $args);
}
add_action('init', 'registerBookPostType');

Explanation:

  • label : Name displayed in the WordPress admin.
  • public : Makes the CPT visible in both frontend and backend.
  • supports : Defines the features available in the editor (title, content, featured image).

Advanced options of register_post_type()

 

1. Creating a backend-only CPT

If you need a CPT accessible only from the backend, set public to false:

<?php
function registerTaskPostType() {
    $args = [
        'label'     => 'Tasks',
        'public'    => false,
        'show_ui'   => true,
        'supports'  => ['title', 'editor'],
    ];
    register_post_type('task', $args);
}
add_action('init', 'registerTaskPostType');

Use case: Ideal for internal tasks or administrative data.

2. Creating a hierarchical CPT (parent and child within the same CPT)

To allow relationships between entries in the same CPT, use the hierarchical argument:

<?php
function registerProjectPostType() {
    $args = [
        'label'        => 'Projects',
        'public'       => true,
        'hierarchical' => true,
        'supports'     => ['title', 'editor'],
    ];
    register_post_type('project', $args);
}
add_action('init', 'registerProjectPostType');

Use case: “Projects” will have a field in the editor to select a “Parent Project.” This is useful for creating hierarchical relationships like main categories or subprojects.

3. Placing the CPT in a specific menu

To make the “Books” CPT appear as a submenu under “Projects,” configure the show_in_menu argument:

<?php
function registerBookPostTypeWithMenu() {
    $args = [
        'label'        => 'Books',
        'public'       => true,
        'show_in_menu' => 'edit.php?post_type=project', // Appears under "Projects"
        'supports'     => ['title', 'editor'],
    ];
    register_post_type('book', $args);
}
add_action('init', 'registerBookPostTypeWithMenu');

 

4. Creating a CPT with custom submenus

Add submenus to the main CPT menu using the add_submenu_page function:

<?php
function registerEventPostType() {
    $args = [
        'label'        => 'Events',
        'public'       => true,
        'show_in_menu' => true,
        'supports'     => ['title', 'editor'],
    ];
    register_post_type('event', $args);

    add_action('admin_menu', function() {
        add_submenu_page(
            'edit.php?post_type=event',
            'Event Settings',
            'Settings',
            'manage_options',
            'event-settings',
            'eventSettingsCallback'
        );
    });
}
add_action('init', 'registerEventPostType');

function eventSettingsCallback() {
    echo '<h1>Event Settings</h1>';
}

Use case: Useful for adding settings or reports related to the CPT.

5. Hiding elements of the admin for a CPT

To create a CPT that’s only accessible from the backend and not visible in searches or the REST API:

<?php
function registerHiddenPostType() {
    $args = [
        'label'               => 'Hidden Items',
        'public'              => true,
        'show_ui'             => true,
        'exclude_from_search' => true,
        'show_in_rest'        => false,
    ];
    register_post_type('hidden_item', $args);
}
add_action('init', 'registerHiddenPostType');

 

 

6. Adding a CPT to the WooCommerce menu

To make the CPT appear as a submenu under WooCommerce’s main menu:

<?php
function registerCouponPostType() {
    $args = [
        'label'        => 'Coupons',
        'public'       => true,
        'show_in_menu' => 'woocommerce', // Adds the CPT to the WooCommerce menu
        'supports'     => ['title', 'editor', 'custom-fields'],
    ];
    register_post_type('coupon', $args);
}
add_action('init', 'registerCouponPostType');

Use case: Organize content directly related to WooCommerce, such as custom coupons.

Custom Post Types are a powerful tool to extend WordPress. Leverage the advanced options of register_post_type() to tailor the user experience and workflow. Document your configurations for easier maintenance and ensure you test your implementations in a development environment.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to Top
0
Would love your thoughts, please comment.x
()
x