Custom Taxonomy Generator
Generate register_taxonomy() code with labels, the post types it applies to, hierarchy, REST support and rewrite rules.
<?php
/**
* Registers the "genre" taxonomy for post.
*/
function my_plugin_register_genre() {
$labels = array(
'name' => _x( 'Genres', 'Taxonomy general name', 'my-plugin' ),
'singular_name' => _x( 'Genre', 'Taxonomy singular name', 'my-plugin' ),
'menu_name' => __( 'Genres', 'my-plugin' ),
'all_items' => __( 'All Genres', 'my-plugin' ),
'edit_item' => __( 'Edit Genre', 'my-plugin' ),
'add_new_item' => __( 'Add New Genre', 'my-plugin' ),
'search_items' => __( 'Search Genres', 'my-plugin' ),
'parent_item' => __( 'Parent Genre', 'my-plugin' ),
'not_found' => __( 'No Genres found.', 'my-plugin' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_in_rest' => true,
'show_admin_column' => true,
'show_in_quick_edit' => true,
'rewrite' => array(
'slug' => 'genre',
'hierarchical' => false,
),
);
register_taxonomy(
'genre',
array_map( 'trim', explode( ',', 'post' ) ),
$args
);
}
add_action( 'init', 'my_plugin_register_genre' );
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Pick the taxonomy key, the post types it applies to and whether it behaves like categories or tags, and the generator writes the register_taxonomy() call with its labels and rewrite rules.
How to use
- Name the taxonomy key. It is stored in the database, capped at 32 characters, and renaming it later means migrating every term relationship.
- List the post types it attaches to, comma separated. They have to be registered by the time this code runs.
- Choose hierarchical for category behaviour, with parents and checkboxes, or leave it off for tag behaviour with a free-text box.
- Set the permalink option. Default uses the taxonomy key as the slug; custom lets you nest it under a path.
- Paste the result into your plugin, then visit Settings, Permalinks once so the rewrite rules are flushed.
Example
A books site adds a flat Topics taxonomy across three post types, nested under a library path, with a default term applied to anything untagged:
$args = array(
'labels' => $labels,
'hierarchical' => false,
'public' => true,
'show_in_rest' => true,
'default_term' => array(
'name' => 'General Interest',
'slug' => 'general-interest',
),
'rewrite' => array(
'slug' => 'library/topics',
'hierarchical' => true,
),
);
register_taxonomy(
'topic',
array_map( 'trim', explode( ',', 'post, book, guide' ) ),
$args
);
show_in_rest is on by default because the block editor’s taxonomy panel does not appear without it, which is the most common reason a new taxonomy seems to register but never shows up.
Pitfalls
- The taxonomy key is capped at 32 characters and cannot be changed without a migration. Term relationships are stored against it.
- Registering on the wrong hook is the usual failure. It must run on
init, notplugins_loadedand not inside awp_loadedcallback. - Rewrite rules are cached. A new or changed slug 404s until permalinks are flushed, which is one visit to Settings, Permalinks.
show_in_restoff means no block editor panel, no matter what the other arguments say.hierarchicalis about behaviour, not appearance. Turning it on after posts are tagged leaves existing terms flat but the UI switches to checkboxes.- A taxonomy key that collides with an existing one, including core’s
categoryandpost_tag, silently wins or loses depending on load order. Prefix it. default_termcreates the term at registration. Changing its name later does not rename the term that already exists.- Attaching to a post type that registers later means the taxonomy is simply not attached; the code runs without an error.
Compatibility
register_taxonomy() has accepted this argument shape since WordPress 4.7, when show_in_rest arrived. default_term needs WordPress 5.5 or later; on older versions the argument is ignored rather than fatal. The generated code targets PHP 7.0 and up, and the tool runs entirely in your browser.
Frequently asked questions
Should this be a taxonomy or a custom field?
Why does my new taxonomy 404 on the front end?
flush_rewrite_rules() on every page load.Can one taxonomy serve several post types?
How do I show it in the block editor?
show_in_rest on. The panel is built from the REST schema, so without it the editor has nothing to render.Does hierarchical change the URL?
/genre/fiction/crime/, which changes existing term links.