WordPress is known for its flexibility, and one of the most powerful features of this platform is Custom Post Types (CPTs). By default, WordPress comes with built-in post types like posts, pages, and attachments, but there are times when you need to create custom content types for more specific purposes. For instance, if you’re building a portfolio website, a “Projects” custom post type would make sense, or if you’re creating a real estate site, a “Properties” custom post type would be useful.
This guide will walk you through creating a custom post type in WordPress, step by step.
What is a Custom Post Type?
A Custom Post Type in WordPress is a way to organize and structure different types of content that don’t fit into the default WordPress post types (such as blog posts and pages). CPTs allow you to extend WordPress and tailor it to your specific needs.
For example, if you’re creating a website for a movie review site, you might want a custom post type for “Movies.” Each movie post type could include fields like title, director, genre, release date, and so on.
Step 1: Set Up Your Development Environment
Before starting, ensure you have access to your WordPress installation either on your local environment or live server. It’s recommended to set up a local development environment for testing. You can use software like XAMPP, MAMP, or Local by Flywheel to create a local server.
Step 2: Register a Custom Post Type with Code
WordPress makes it easy to register a new custom post type using the register_post_type()
function. You’ll need to add this function to your theme’s functions.php
file or a custom plugin.
Here’s how you can register a custom post type called “Books”:
- Open your theme’s
functions.php
file:
Navigate towp-content/themes/your-theme/functions.php
and open it for editing. - Add the custom post type code:
Use theregister_post_type()
function to define your custom post type. Below is a basic example to create a “Books” custom post type:
function create_books_post_type() {
$labels = array(
'name' => _x('Books', 'Post Type General Name', 'textdomain'),
'singular_name' => _x('Book', 'Post Type Singular Name', 'textdomain'),
'menu_name' => __('Books', 'textdomain'),
'name_admin_bar' => __('Book', 'textdomain'),
'add_new_item' => __('Add New Book', 'textdomain'),
'new_item' => __('New Book', 'textdomain'),
'edit_item' => __('Edit Book', 'textdomain'),
'view_item' => __('View Book', 'textdomain'),
'all_items' => __('All Books', 'textdomain'),
'search_items' => __('Search Books', 'textdomain'),
'not_found' => __('No books found', 'textdomain'),
'not_found_in_trash' => __('No books found in Trash', 'textdomain'),
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'books'),
'supports' => array('title', 'editor', 'excerpt', 'thumbnail', 'comments', 'revisions'),
'menu_position' => 5,
'menu_icon' => 'dashicons-book', // Dashicon for the menu item
'show_in_rest' => true, // For enabling Gutenberg editor
);
register_post_type('books', $args);
}
add_action('init', 'create_books_post_type');
Explanation of Code:
- Labels: The
$labels
array defines how the custom post type will be displayed in the WordPress admin interface. It sets names like “Add New Book,” “All Books,” etc. - Args: The
$args
array configures the post type. Here’s a breakdown of the key options:public
: Determines whether the post type is public.has_archive
: If true, enables an archive page for this post type (e.g.,yoursite.com/books
).rewrite
: Defines the URL slug for this post type.supports
: Specifies which fields (title, editor, thumbnail, etc.) the post type should support.menu_icon
: Specifies the icon displayed in the WordPress dashboard. You can use Dashicons for this.show_in_rest
: Enables Gutenberg editor support for the custom post type.
Step 3: Customize the Custom Post Type Further
You can further customize your custom post type with different options, depending on your needs. Below are a few advanced configurations:
1. Hierarchical Custom Post Types (Like Pages)
If you want your custom post type to behave like pages (i.e., with parent and child posts), set hierarchical
to true
in the $args
array:
'hierarchical' => true,
This allows you to create parent-child relationships between posts.
2. Add Custom Taxonomies
Custom taxonomies let you categorize your custom post type. For example, if you’re creating a “Books” post type, you might want to categorize them by genre.
Here’s how to register a custom taxonomy called “Genre” for the “Books” post type:
function create_genre_taxonomy() {
$labels = array(
'name' => _x('Genres', 'taxonomy general name', 'textdomain'),
'singular_name' => _x('Genre', 'taxonomy singular name', 'textdomain'),
'search_items' => __('Search Genres', 'textdomain'),
'all_items' => __('All Genres', 'textdomain'),
'parent_item' => __('Parent Genre', 'textdomain'),
'parent_item_colon' => __('Parent Genre:', 'textdomain'),
'edit_item' => __('Edit Genre', 'textdomain'),
'update_item' => __('Update Genre', 'textdomain'),
'add_new_item' => __('Add New Genre', 'textdomain'),
'new_item_name' => __('New Genre Name', 'textdomain'),
'menu_name' => __('Genres', 'textdomain'),
);
$args = array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'genre'),
);
register_taxonomy('genre', array('books'), $args);
}
add_action('init', 'create_genre_taxonomy');
3. Custom Meta Boxes
You can add custom meta boxes to your custom post types to collect additional information. For example, if you’re working with “Books,” you might want to collect information like author, publisher, and publication year.
function add_books_meta_boxes() {
add_meta_box('book_details', 'Book Details', 'book_details_callback', 'books', 'normal', 'high');
}
function book_details_callback($post) {
// Meta box HTML goes here
echo '<label for="book_author">Author:</label>';
echo '<input type="text" id="book_author" name="book_author" value="' . get_post_meta($post->ID, 'book_author', true) . '" />';
}
add_action('add_meta_boxes', 'add_books_meta_boxes');
This creates a custom meta box in the WordPress admin for your “Books” custom post type.
Step 4: Display Your Custom Post Type on the Frontend
Once you’ve created your custom post type, you’ll want to display it on the front end of your site.
1. Create a Custom Archive Page
To create a custom archive page for your custom post type, create a file called archive-books.php
in your theme folder. This will be used to display the archive page for your custom post type.
<?php get_header(); ?>
<h1>Books Archive</h1>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div><?php the_excerpt(); ?></div>
</article>
<?php endwhile; else : ?>
<p>No books found</p>
<?php endif; ?>
<?php get_footer(); ?>
This template will automatically display all posts of the “Books” custom post type.
2. Create a Single Post Template
You can also create a custom template for displaying individual posts of your custom post type. Create a file called single-books.php
in your theme folder:
<?php get_header(); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<article>
<h1><?php the_title(); ?></h1>
<div><?php the_content(); ?></div>
</article>
<?php endwhile; endif; ?>
<?php get_footer(); ?>
This template will be used whenever you view a single “Book” post.