Create Custom Post Types in WordPress

WordPress stores its content as post types and also allows us to add custom post types. Learn how to create a custom post type without using a plugin.

Create Custom Post Types in Wordpress

WordPress offers a feature to add a WordPress Custom Post Type, also shortened as CPT. This feature allows developers to register different post types in addition to other default post types in WordPress. In this post, we are going to create a custom post type called "property" which represents a real estate property.

 

Post Types in WordPress

Taken from the WordPress official Post Types page, every single item is called a post, which is also the default post type of WordPress. By default, WordPress comes with the following post types:

  • Posts: A default post type for all blog posts.
  • Pages: A post type for pages and can create a hierarchical page structure.
  • Revisions: A special post type used to keep a history of other post types.
  • Attachments: A special post type that stores information about all the uploaded media.
  • Menus: A post type used to create menus for navigation purposes on the website.
  • Custom CSS: A theme specific post type to store CSS changes saved from the customizer (Additional CSS).
  • Changesets: These post types are like revisions, but store the history of changes made from the customizer.

How to Create A Custom Post Type in WordPress

We will create a cpts.php file and place our code in this file. Then we will include this file in the theme's functions.php file. We are going to use the init hook of WordPress and use the register_post_type function to register a custom post type. This is how the function is used:

register_post_type('your_post_type', $arguments);

The first parameter is your custom type slug, and the second parameter is an array of arguments for our custom post type or/and any other custom post types. For a complete definition of parameters, visit WordPress Register Post Type.

Steps to create a custom type in WordPress without using any plugin:

  • Add an action hook for init() with the custom_cpts() function.
  • Inside the function custom_cpts(), define an array of labels.
  • Set argument parameters for the custom post type.
  • Set labels, menu icon, and support array parameter for the post type.
  • Call the function register_post_type() to create a custom post type.
  • Provide a unique slug for the post type and pass the arguments array we prepared as the second parameter.

cpts.php

<?php
// Register Post Type on init Hook
add_action('init', 'custom_cpts');
function custom_cpts(): void
{
// --- Labels Array --- //

// General name for the post type, usually plural
$labels['name'] = __('Properties', 'text-domain');

// Name for one object of this post type
$labels['singular_name'] = __('Property', 'text-domain');

// Label to signify all items in a submenu link
$labels['all_items'] = __('All Properties', 'text-domain');

// Label for adding a new singular item button on list screen
$labels['add_new'] = __('Add Property', 'text-domain');

// Label for adding a new singular item
$labels['add_new_item'] = __('Add New Property', 'text-domain');

// Label for editing a singular item
$labels['edit_item'] = __('Edit Property', 'text-domain');

// Label for the new item page title
$labels['new_item'] = __('New Property', 'text-domain');

// Label for viewing a singular item
$labels['view_item'] = __('View Property', 'text-domain');

// Label for viewing post type archives
$labels['view_items'] = __('View Properties', 'text-domain');

// Label for searching plural items
$labels['search_items'] = __('Search Property', 'text-domain');

// When no properties are found in admin screen
$labels['not_found'] = __('No Properties Found', 'text-domain');

//--- Custom Post Type Arguments ---//

// Name of the post type shown in the menu.
$cpt_args['label'] = __('Properties', 'text-domain');
$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-admin-multisite';

// 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('property', $cpt_args);
}
 
Create Custom Post Types in Wordpress

We just demonstrated how easy it is to register a custom post type in WordPress with a simple block of PHP code. We can further register custom taxonomies and add custom post meta fields for the post type we created.