Creates or modifies a taxonomy object.
Description
Note: Do not use before the ‘init’ hook.
A simple function for creating or modifying a taxonomy object based on the parameters given. If modifying an existing taxonomy object, note that the $object_type
value from the original registration will be overwritten.
Parameters
$taxonomy
stringrequired- Taxonomy key. Must not exceed 32 characters and may only contain lowercase alphanumeric characters, dashes, and underscores. See sanitize_key() .
$object_type
array|stringrequired- Object type or array of object types with which the taxonomy should be associated.
$args
array|stringoptional- Array or query string of arguments for registering a taxonomy.
labels
string[]An array of labels for this taxonomy. By default, Tag labels are used for non-hierarchical taxonomies, and Category labels are used for hierarchical taxonomies. See accepted values in get_taxonomy_labels() .description
stringA short descriptive summary of what the taxonomy is for.public
boolWhether a taxonomy is intended for use publicly either via the admin interface or by front-end users. The default settings of$publicly_queryable
,$show_ui
, and$show_in_nav_menus
are inherited from$public
.publicly_queryable
boolWhether the taxonomy is publicly queryable.
If not set, the default is inherited from$public
hierarchical
boolWhether the taxonomy is hierarchical. Default false.show_ui
boolWhether to generate and allow a UI for managing terms in this taxonomy in the admin. If not set, the default is inherited from$public
(default true).show_in_menu
boolWhether to show the taxonomy in the admin menu. If true, the taxonomy is shown as a submenu of the object type menu. If false, no menu is shown.
$show_ui
must be true. If not set, default is inherited from$show_ui
(default true).show_in_nav_menus
boolMakes this taxonomy available for selection in navigation menus. If not set, the default is inherited from$public
(default true).show_in_rest
boolWhether to include the taxonomy in the REST API. Set this to true for the taxonomy to be available in the block editor.rest_base
stringTo change the base url of REST API route. Default is $taxonomy.rest_namespace
stringTo change the namespace URL of REST API route. Default is wp/v2.rest_controller_class
stringREST API Controller class name. Default is ‘WP_REST_Terms_Controller‘.show_tagcloud
boolWhether to list the taxonomy in the Tag Cloud Widget controls. If not set, the default is inherited from$show_ui
(default true).show_in_quick_edit
boolWhether to show the taxonomy in the quick/bulk edit panel. It not set, the default is inherited from$show_ui
(default true).show_admin_column
boolWhether to display a column for the taxonomy on its post type listing screens. Default false.meta_box_cb
bool|callableProvide a callback function for the meta box display. If not set, post_categories_meta_box() is used for hierarchical taxonomies, and post_tags_meta_box() is used for non-hierarchical. If false, no meta box is shown.meta_box_sanitize_cb
callableCallback function for sanitizing taxonomy data saved from a meta box. If no callback is defined, an appropriate one is determined based on the value of$meta_box_cb
.capabilities
string[]Array of capabilities for this taxonomy.manage_terms
stringDefault'manage_categories'
.edit_terms
stringDefault'manage_categories'
.delete_terms
stringDefault'manage_categories'
.assign_terms
stringDefault'edit_posts'
.
rewrite
bool|arrayTriggers the handling of rewrites for this taxonomy. Default true, using $taxonomy as slug. To prevent rewrite, set to false. To specify rewrite rules, an array can be passed with any of these keys:slug
stringCustomize the permastruct slug. Default$taxonomy
key.with_front
boolShould the permastruct be prepended with WP_Rewrite::$front. Default true.hierarchical
boolEither hierarchical rewrite tag or not. Default false.ep_mask
intAssign an endpoint mask. DefaultEP_NONE
.
query_var
string|boolSets the query var key for this taxonomy. Default$taxonomy
key. If false, a taxonomy cannot be loaded at?{query_var}={term_slug}
. If a string, the query?{query_var}={term_slug}
will be valid.update_count_callback
callableWorks much like a hook, in that it will be called when the count is updated. Default _update_post_term_count() for taxonomies attached to post types, which confirms that the objects are published before counting them. Default _update_generic_term_count() for taxonomies attached to other object types, such as users.default_term
string|arrayDefault term to be used for the taxonomy.name
stringName of default term.slug
stringSlug for default term.description
stringDescription for default term.
sort
boolWhether terms in this taxonomy should be sorted in the order they are provided towp_set_object_terms()
. Default null which equates to false.args
arrayArray of arguments to automatically use insidewp_get_object_terms()
for this taxonomy._builtin
boolThis taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY! Default false.
Default:
array()
Source
function register_taxonomy( $taxonomy, $object_type, $args = array() ) { global $wp_taxonomies; if ( ! is_array( $wp_taxonomies ) ) { $wp_taxonomies = array(); } $args = wp_parse_args( $args ); if ( empty( $taxonomy ) || strlen( $taxonomy ) > 32 ) { _doing_it_wrong( __FUNCTION__, __( 'Taxonomy names must be between 1 and 32 characters in length.' ), '4.2.0' ); return new WP_Error( 'taxonomy_length_invalid', __( 'Taxonomy names must be between 1 and 32 characters in length.' ) ); } $taxonomy_object = new WP_Taxonomy( $taxonomy, $object_type, $args ); $taxonomy_object->add_rewrite_rules(); $wp_taxonomies[ $taxonomy ] = $taxonomy_object; $taxonomy_object->add_hooks(); // Add default term. if ( ! empty( $taxonomy_object->default_term ) ) { $term = term_exists( $taxonomy_object->default_term['name'], $taxonomy ); if ( $term ) { update_option( 'default_term_' . $taxonomy_object->name, $term['term_id'] ); } else { $term = wp_insert_term( $taxonomy_object->default_term['name'], $taxonomy, array( 'slug' => sanitize_title( $taxonomy_object->default_term['slug'] ), 'description' => $taxonomy_object->default_term['description'], ) ); // Update `term_id` in options. if ( ! is_wp_error( $term ) ) { update_option( 'default_term_' . $taxonomy_object->name, $term['term_id'] ); } } } /** * Fires after a taxonomy is registered. * * @since 3.3.0 * * @param string $taxonomy Taxonomy slug. * @param array|string $object_type Object type or array of object types. * @param array $args Array of taxonomy registration arguments. */ do_action( 'registered_taxonomy', $taxonomy, $object_type, (array) $taxonomy_object ); /** * Fires after a specific taxonomy is registered. * * The dynamic portion of the filter name, `$taxonomy`, refers to the taxonomy key. * * Possible hook names include: * * - `registered_taxonomy_category` * - `registered_taxonomy_post_tag` * * @since 6.0.0 * * @param string $taxonomy Taxonomy slug. * @param array|string $object_type Object type or array of object types. * @param array $args Array of taxonomy registration arguments. */ do_action( "registered_taxonomy_{$taxonomy}", $taxonomy, $object_type, (array) $taxonomy_object ); return $taxonomy_object; }
Hooks
- do_action( ‘registered_taxonomy’,
string $taxonomy ,array|string $object_type ,array $args ) Fires after a taxonomy is registered.
- do_action( “registered_taxonomy_{$taxonomy}”,
string $taxonomy ,array|string $object_type ,array $args ) Fires after a specific taxonomy is registered.
Changelog
Show 4 moreShow lessVersion Description 5.9.0 Introduced rest_namespace
argument.5.5.0 Introduced default_term
argument.5.4.0 Added the registered taxonomy object as a return value. 5.1.0 Introduced meta_box_sanitize_cb
argument.4.7.0 Introduced show_in_rest
,'rest_base'
and'rest_controller_class'
arguments to register the taxonomy in REST API.4.5.0 Introduced publicly_queryable
argument.4.4.0 The public
argument now controls whether the taxonomy can be queried on the front end.4.2.0 Introduced show_in_quick_edit
argument.2.3.0 Introduced. User Contributed Notes
You must log in before being able to contribute a note or feedback.
If you want your taxonomy panel to be visible at the sidebar of the block editor, you should set
show_in_rest
totrue
.In order to have a taxonomy appear in the URL hierarchy of the relevant CPT, you can rewrite the taxonomy slug to contain the CPT’s slug. But you must register the CPT after registering the taxonomy, otherwise the rewrite will not work, i.e. in this case, book CPT must be registered after genre taxonomy.
HT: https://cnpagency.com/blog/the-right-way-to-do-wordpress-custom-taxonomy-rewrites/
Be careful not to use a reserved word for
slug
,query_var
or$taxonomy name
. See WP_Query for a list of them.This includes words like “author”. If you attempt to use “author” as a taxonomy and/or override the default
slug
orquery_var
of a custom taxonomy to match these words, they will not work correctly.The administration will be fine (a menu is shown, terms can be created and associated etc.). But the front-end will not work correctly. For example a url `https://example.org/author/name`, should probably display no results (if it is looking for post authors, instead of your taxonomy). But instead, it seems to first try both during the rewrite matching, but then the actual query filters neither. End result the query is empty and matches all results, and WordPress displays your home page (not even `archive.php`).
As of WordPress 4.9.5, there is no warning for this when you accidentally use one of these words.
Note that the taxonomy name – the
$taxonomy
param above – should include only the charactersa-z0-9_
. It may appear to work when you register a taxonomy that has, say, a capital letter. But there are various places in WP where the taxonomy slug is run throughsanitize_key()
– such as during AJAX tag searches – which will lead to subtle sorts of breakage.Registering two taxonomies for a post type
This example registers two taxonomies, genres and writers, for the post type called “book”.
Note: You can define custom taxonomies in a theme’s
functions.php
template file:Example Private Taxonomy
If you do not want your taxonomy to be exposed publicly, you can use the
public
andrewrite
parameters to suppress it. It will be available to use internally by your plugin or theme, but will not generate a url of it’s own.NOTE: The ‘meta_box_cb’ argument is not supported with Gutenberg editor
The statement: If you want to ensure that your custom taxonomy behaves like a tag, you must add the option
'update_count_callback' => '_update_post_term_count'
is no longer true, at least as of version 4.6.1, perhaps even earlier.Simply declaring a taxonomy as non-hierarchical, behaves exactly like a tag.
Note two undocumented configuration arguments of `register_taxonomy` (the `$args` array keys): `sort` and `args`. Setting `sort` to `true` will have WordPress retain the order in which terms are added to objects. Setting `args` lets you specify an array of configuration parameters that, when present, override corresponding parameters in the `$args` array passed to `wp_get_object_terms` when using that function to query for terms in the specified taxonomy. This allows the order of terms to be displayed in the order they were defined in the editor.
The bug presented in ticket #40496 (https://core.trac.wordpress.org/ticket/40496) introduced these undocumented features to me.
For registering a custom taxonomy (with hierarchical set to true), and wanting all the labels options set – and Gutenberg editor ready (show_in_rest => true). Here is the code.
If you want to use the dynamic capabilities for taxonomy to be displayed and managed from frontend then append the ‘capabilities’ key with the array like below.
Since Gutenberg 13.3 (and WP 6.1), a post term block variation is generated for each registered custom taxonomy. For example, if you register a “Product category” taxonomy, you should able to add a “Product categories” block that lists all the product category terms assigned to the current post.
But, currently, for the post term block variation automatic generation to work you need to register the custom taxonomies earlier in the process (a priority lower than 10).
Example:
add_action( 'init', 'wpdocs_register_taxonomies', 9 );
Registering multiple taxonomies in array for specific post type.
To hide a taxonomy metabox when using Gutenberg you must enqueue a script in admin that does this:
wp.data.dispatch( 'core/edit-post').removeEditorPanel( 'taxonomy-panel-[taxonomy_key]' );
Replace
[taxonomy_key]
with your taxonomy key.As per https://core.trac.wordpress.org/ticket/41813 if you use this to add a custom taxonomy to media/attachments. You may find that all works well except the count of the terms when using get_terms ( which returns nothing ).
To fix this you may need to use this call in register_taxonomy
'update_count_callback' => '_update_generic_term_count',
( https://core.trac.wordpress.org/ticket/41813#comment:8 )
Basic Example
Note: If you want to ensure that your custom taxonomy behaves like a tag, you must add the option
'update_count_callback' => '_update_post_term_count'
. Not doing so will result in multiple comma-separated items added at once being saved as a single value, not as separate values. This can cause undue stress when usingget_the_term_list()
and other term display functions.