Custom Post Types in WordPress
Register a Custom Post Type
Use the WP function register_post_type() with the init action hook in the functions.php theme file to define a custom Post Type.
NOTE: It is necessary to simply save the Settings > Permalinks page to make the new post type register.
NOTE: The custom post type archive page will be in a (slug friendly) URL path named after the post-type. In the example below, a new "Visual Art" posts will be at mysite.com/visual-art/my-post/ and the archive page will be at mysite.com/visual-art/.
// `Visual Art` custom post type function.
function create_art_posttype() {
register_post_type( 'visual_art',
// CPT Options
[
'labels' => [
'name' => __('Visual Art', 'wph-text-domain'),
'singular_name' => __('Visual Art', 'wph-text-domain'),
'menu_name' => __('Visual Art', 'wph-text-domain'),
'parent_item_colon' => __('Parent Visual Art', 'wph-text-domain'),
'all_items' => __('All Visual Art', 'wph-text-domain'),
'view_item' => __('View Visual Art', 'wph-text-domain'),
'add_new_item' => __('Add New Visual Art', 'wph-text-domain'),
'add_new' => __('Add New Visual Art', 'wph-text-domain'),
'edit_item' => __('Edit Visual Art', 'wph-text-domain'),
'update_item' => __('Update Visual Art', 'wph-text-domain'),
'search_items' => __('Search Visual Art', 'wph-text-domain'),
'not_found' => __('Visual Art Not Found', 'wph-text-domain'),
'not_found_in_trash' => __('Visual Art Not found in Trash', 'wph-text-domain'),
],
'public' => true,
'has_archive' => true,
'rewrite' => ['slug' => 'visual-art'],
'show_in_rest' => true,
'capability_type' => 'post',
// Taxonomies.
'taxonomies' => ['post_tag'],
// Features this custom post type supports in Post Editor
'supports' => ['title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields',],
// A hierarchical custom post type is like Pages and can have
// Parent and child items. A non-hierarchical custom post type
// is like Posts.
'hierarchical' => false,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'can_export' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
]
);
}
// Hooking up our function to theme setup
add_action( 'init', 'create_art_posttype' );
Custom Post Type Thumbnail Support
Thumbnail support must be specifically added to a custom post type.
// Add the `visual_art` custom post type thumbnails to the theme.
function add_visual_art_theme_supports() {
// Add thumbnail support to the `art` type template files.
add_theme_support('post-thumbnails', ['visual_art']);
}
add_action('after_setup_theme', 'add_visual_art_theme_supports');
Custom Post Type Conditionals
Custom post types will respect the normal is_single() and is_archive() functions but you can also check for specific post types with the is_singular() and get_post_type() functions.
// Single custom post type page.
if( is_singular( 'visual_art' ) )
{
do something.
}
// Check within The Loop.
if( 'visual_art' == get_post_type() )
{
do something.
}
Custom Post Type Template Files
The default template files for a custom post type are single-{post type ID}.php and archive-{post type ID}.php. So for the Visual Art post type they would be:
single-visual_art.php
archive-visual_art.php
Add a Custom Post Type to the Main Query
// Add custom post-types to the 'Main Query' (Home page).
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );
function add_my_post_types_to_query( $query )
{
if ( is_home() && $query->is_main_query() )
{
$query->set( 'post_type', array(
'post', // Keep the standard 'posts' in the Main Query.
'visual_art ', // Add the custom post-type 'visual_art ' to the Main Query.
//'page', // Add pages to the Main Query.
) );
}
return $query;
}