register_taxonomy( string $taxonomy, array|string $object_type, array|string $args = array() )

Creates or modifies a taxonomy object.


Description 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 Parameters

$taxonomy

(string) (Required) Taxonomy key, must not exceed 32 characters.

$object_type

(array|string) (Required) Object type or array of object types with which the taxonomy should be associated.

$args

(array|string) (Optional) Array or query string of arguments for registering a taxonomy.

  • 'labels'
    (array) 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'
    (string) A short descriptive summary of what the taxonomy is for.
  • 'public'
    (bool) Whether 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'
    (bool) Whether the taxonomy is publicly queryable. If not set, the default is inherited from $public
  • 'hierarchical'
    (bool) Whether the taxonomy is hierarchical. Default false.
  • 'show_ui'
    (bool) Whether 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'
    (bool) Whether 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'
    (bool) Makes this taxonomy available for selection in navigation menus. If not set, the default is inherited from $public (default true).
  • 'show_in_rest'
    (bool) Whether to include the taxonomy in the REST API.
  • 'rest_base'
    (string) To change the base url of REST API route. Default is $taxonomy.
  • 'rest_controller_class'
    (string) REST API Controller class name. Default is 'WP_REST_Terms_Controller'.
  • 'show_tagcloud'
    (bool) Whether 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'
    (bool) Whether 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'
    (bool) Whether to display a column for the taxonomy on its post type listing screens. Default false.
  • 'meta_box_cb'
    (bool|callable) Provide 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'
    (callable) Callback 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'
    (array) Array of capabilities for this taxonomy.
    • 'manage_terms'
      (string) Default 'manage_categories'.
    • 'edit_terms'
      (string) Default 'manage_categories'.
    • 'delete_terms'
      (string) Default 'manage_categories'.
    • 'assign_terms'
      (string) Default 'edit_posts'.
  • 'rewrite'
    (bool|array) Triggers 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'
      (string) Customize the permastruct slug. Default $taxonomy key.
    • 'with_front'
      (bool) Should the permastruct be prepended with WP_Rewrite::$front. Default true.
    • 'hierarchical'
      (bool) Either hierarchical rewrite tag or not. Default false.
    • 'ep_mask'
      (int) Assign an endpoint mask. Default EP_NONE.
  • 'query_var'
    (string) Sets 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'
    (callable) Works 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.
  • '_builtin'
    (bool) This taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY! Default false.

Default value: array()


Top ↑

Return Return

(WP_Error|void) WP_Error, if errors.


Top ↑

Source Source

File: wp-includes/taxonomy.php

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();

	/**
	 * 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 );
}

Top ↑

Changelog Changelog

Changelog
Version Description
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.


Top ↑

User Contributed Notes User Contributed Notes

  1. Skip to note 1 content
    Contributed by Codex

    Example Private Taxonomy

    If you do not want your taxonomy to be exposed publicly, you can use the public and rewrite 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.

    /**
     * Register a private 'Genre' taxonomy for post type 'book'.
     *
     * @see register_post_type() for registering post types.
     */
    function wpdocs_register_private_taxonomy() {
     	$args = array(
    		'label'        => __( 'Genre', 'textdomain' ),
    		'public'       => false,
    		'rewrite'      => false,
    		'hierarchical' => true
    	);
    	
    	register_taxonomy( 'genre', 'book', $args );
    }
    add_action( 'init', 'wpdocs_register_private_taxonomy', 0 );
    
  2. Skip to note 2 content
    Contributed by Matt Radford

    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/

    /**
     * Register a 'genre' taxonomy for post type 'book', with a rewrite to match book CPT slug.
     *
     * @see register_post_type for registering post types.
     */
    function wpdocs_create_book_tax_rewrite() {
        register_taxonomy( 'genre', 'book', array(
            'rewrite'      => array( 'slug' => 'books/genre' )
        ) );
    }
    add_action( 'init', 'wpdocs_create_book_tax_rewrite', 0 );
  3. Skip to note 3 content
    Contributed by Boone Gorges

    Note that the taxonomy name – the $taxonomy param above – should include only the characters a-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 through sanitize_key() – such as during AJAX tag searches – which will lead to subtle sorts of breakage.

  4. Skip to note 4 content

    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.

  5. Skip to note 5 content
    Contributed by TimoTijhof

    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 or query_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.

  6. Skip to note 6 content
    Contributed by Dilip Gupta

    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.

    /**
     * Register a 'genre' taxonomy for post type 'book'.
     *
     * Register custom capabilities for taxonomies.
     *
     * @see register_post_type for registering post types.
     */
    function wpdocs_create_book_tax() {
        register_taxonomy( 'genre', 'book', array(
            'label'        => __( 'Genre', 'textdomain' ),
            'rewrite'      => array( 'slug' => 'genre' ),
            'hierarchical' => true,
    		'capabilities' => array(
    			// $taxonomy['slug'] = genre;
    			'manage_terms'	=>	'manage_'.$taxonomy['slug'],
    			'edit_terms'	=>	'edit_'.$taxonomy['slug'],
    			'delete_terms'	=>	'delete'.$taxonomy['slug'],
    			'assign_terms'	=>	'assign_'.$taxonomy['slug'],
    		),
        ) );
    }
    add_action( 'init', 'wpdocs_create_book_tax', 0 );
    
  7. Skip to note 7 content
    Contributed by Sean Leavey

    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.

  8. Skip to note 8 content
    Contributed by Codex

    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:

    /**
     * Create two taxonomies, genres and writers for the post type "book".
     *
     * @see register_post_type() for registering custom post types.
     */
    function wpdocs_create_book_taxonomies() {
    	// Add new taxonomy, make it hierarchical (like categories)
    	$labels = array(
    		'name'              => _x( 'Genres', 'taxonomy general name', 'textdomain' ),
    		'singular_name'     => _x( 'Genre', 'taxonomy singular name', 'textdomain' ),
    		'search_items'      => __( 'Search Genres', 'textdomain' ),
    		'all_items'         => __( 'All Genres', 'textdomain' ),
    		'parent_item'       => __( 'Parent Genre', 'textdomain' ),
    		'parent_item_colon' => __( 'Parent Genre:', 'textdomain' ),
    		'edit_item'         => __( 'Edit Genre', 'textdomain' ),
    		'update_item'       => __( 'Update Genre', 'textdomain' ),
    		'add_new_item'      => __( 'Add New Genre', 'textdomain' ),
    		'new_item_name'     => __( 'New Genre Name', 'textdomain' ),
    		'menu_name'         => __( 'Genre', 'textdomain' ),
    	);
    
    	$args = array(
    		'hierarchical'      => true,
    		'labels'            => $labels,
    		'show_ui'           => true,
    		'show_admin_column' => true,
    		'query_var'         => true,
    		'rewrite'           => array( 'slug' => 'genre' ),
    	);
    
    	register_taxonomy( 'genre', array( 'book' ), $args );
    
    	unset( $args );
    	unset( $labels );
    
    	// Add new taxonomy, NOT hierarchical (like tags)
    	$labels = array(
    		'name'                       => _x( 'Writers', 'taxonomy general name', 'textdomain' ),
    		'singular_name'              => _x( 'Writer', 'taxonomy singular name', 'textdomain' ),
    		'search_items'               => __( 'Search Writers', 'textdomain' ),
    		'popular_items'              => __( 'Popular Writers', 'textdomain' ),
    		'all_items'                  => __( 'All Writers', 'textdomain' ),
    		'parent_item'                => null,
    		'parent_item_colon'          => null,
    		'edit_item'                  => __( 'Edit Writer', 'textdomain' ),
    		'update_item'                => __( 'Update Writer', 'textdomain' ),
    		'add_new_item'               => __( 'Add New Writer', 'textdomain' ),
    		'new_item_name'              => __( 'New Writer Name', 'textdomain' ),
    		'separate_items_with_commas' => __( 'Separate writers with commas', 'textdomain' ),
    		'add_or_remove_items'        => __( 'Add or remove writers', 'textdomain' ),
    		'choose_from_most_used'      => __( 'Choose from the most used writers', 'textdomain' ),
    		'not_found'                  => __( 'No writers found.', 'textdomain' ),
    		'menu_name'                  => __( 'Writers', 'textdomain' ),
    	);
    
    	$args = array(
    		'hierarchical'          => false,
    		'labels'                => $labels,
    		'show_ui'               => true,
    		'show_admin_column'     => true,
    		'update_count_callback' => '_update_post_term_count',
    		'query_var'             => true,
    		'rewrite'               => array( 'slug' => 'writer' ),
    	);
    
    	register_taxonomy( 'writer', 'book', $args );
    }
    // hook into the init action and call create_book_taxonomies when it fires
    add_action( 'init', 'wpdocs_create_book_taxonomies', 0 );
    
  9. Skip to note 9 content
    Contributed by Codex

    Basic Example

    /**
     * Register a 'genre' taxonomy for post type 'book'.
     *
     * @see register_post_type for registering post types.
     */
    function wpdocs_create_book_tax() {
    	register_taxonomy( 'genre', 'book', array(
    		'label'        => __( 'Genre', 'textdomain' ),
    		'rewrite'      => array( 'slug' => 'genre' ),
    		'hierarchical' => true,
    	) );
    }
    add_action( 'init', 'wpdocs_create_book_tax', 0 );
    

    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 using get_the_term_list() and other term display functions.

You must log in before being able to contribute a note or feedback.