How to Use register_post_type in WordPress to Create Custom Post Types
Use the
register_post_type function in WordPress to create custom post types by providing a unique name and an array of settings. This function is typically called inside the init action hook to register the post type when WordPress loads.Syntax
The register_post_type function requires two main parameters: a unique post type key (string) and an array of arguments to define labels and behavior.
- $post_type: A unique string identifier for your custom post type (e.g., 'book').
- $args: An array of options like labels, visibility, supports, and rewrite rules.
It is best to call this function inside the init hook to ensure WordPress is ready.
php
function register_my_custom_post_type() { register_post_type('your_post_type', [ 'labels' => [ 'name' => 'Your Post Types', 'singular_name' => 'Your Post Type' ], 'public' => true, 'has_archive' => true, 'supports' => ['title', 'editor', 'thumbnail'], 'rewrite' => ['slug' => 'your-post-types'] ]); } add_action('init', 'register_my_custom_post_type');
Example
This example registers a custom post type called Book with support for title, editor, and thumbnail. It will appear in the WordPress admin menu and have its own archive page.
php
<?php function register_book_post_type() { register_post_type('book', [ 'labels' => [ 'name' => 'Books', 'singular_name' => 'Book', 'add_new' => 'Add New Book', 'add_new_item' => 'Add New Book', 'edit_item' => 'Edit Book', 'new_item' => 'New Book', 'view_item' => 'View Book', 'search_items' => 'Search Books', 'not_found' => 'No books found', 'not_found_in_trash' => 'No books found in Trash' ], 'public' => true, 'has_archive' => true, 'menu_position' => 5, 'supports' => ['title', 'editor', 'thumbnail'], 'rewrite' => ['slug' => 'books'], 'show_in_rest' => true ]); } add_action('init', 'register_book_post_type');
Output
A new 'Books' menu appears in the WordPress admin sidebar, allowing creation and management of Book posts with title, content editor, and featured image support. The URL example: yoursite.com/books shows the archive of all books.
Common Pitfalls
- Not using the
inithook: Callingregister_post_typeoutside ofinitcan cause the post type not to register properly. - Using reserved or invalid post type names: Post type keys must be lowercase, no spaces, and less than 20 characters.
- Forgetting
show_in_restfor Gutenberg support: Withoutshow_in_restset to true, the post type won't support the block editor. - Not flushing rewrite rules: After registering a new post type with custom slugs, permalinks may 404 until you visit Settings > Permalinks to flush rewrite rules.
php
<?php // Wrong: calling outside init register_post_type('movie', ['public' => true]); // Right: inside init hook add_action('init', function() { register_post_type('movie', ['public' => true]); });
Quick Reference
| Parameter | Description | Example |
|---|---|---|
| $post_type | Unique key for the post type (lowercase, no spaces) | 'book' |
| labels | Array of names shown in admin UI | {'name' => 'Books', 'singular_name' => 'Book'} |
| public | Makes post type visible on front and admin | true |
| has_archive | Enables archive page for post type | true |
| supports | Features supported like title, editor, thumbnail | ['title', 'editor', 'thumbnail'] |
| rewrite | Custom URL slug settings | {'slug' => 'books'} |
| show_in_rest | Enable Gutenberg editor support | true |
Key Takeaways
Always register custom post types inside the init hook using register_post_type.
Use a unique, lowercase, and short string as the post type key.
Set show_in_rest to true to enable block editor support.
Flush rewrite rules after registering new post types to avoid 404 errors.
Customize labels and supports array to control admin UI and features.