dev3 ·
I want a "Projects" content type with its own categories. Should I put register_post_type in my theme's functions.php, and what arguments matter?
#wordpress#custom-post-type#php
0
Every post is reviewed first. Usually reviewed within 24 hours.
I want a "Projects" content type with its own categories. Should I put register_post_type in my theme's functions.php, and what arguments matter?
#wordpress#custom-post-type#php
Register content types in a plugin, not the theme. If the theme is switched, content types in functions.php vanish and your posts become inaccessible (they remain in the database).
<?php
/**
* Plugin Name: Projects CPT
*/
function acme_register_types() {
register_post_type( 'project', array(
'labels' => array( 'name' => 'Projects', 'singular_name' => 'Project' ),
'public' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'projects' ),
'show_in_rest' => true, // block editor + REST API
'menu_icon' => 'dashicons-portfolio',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
) );
register_taxonomy( 'project_type', 'project', array(
'label' => 'Project types',
'hierarchical' => true,
'show_in_rest' => true,
'rewrite' => array( 'slug' => 'project-type' ),
) );
}
add_action( 'init', 'acme_register_types' );
register_activation_hook( __FILE__, function () {
acme_register_types(); // register first (init has already run), then flush once
flush_rewrite_rules();
} );
Key points
show_in_rest => true is required for the block editor and REST access.rewrite or has_archive, flush once (Settings > Permalinks > Save, or wp rewrite flush). Never flush on each request.project is fine for private sites, but vendors usually use acme_project).single-project.php and archive-project.php.A full worked example with a taxonomy is in the DEV3 snippet library.