In WordPress, a “taxonomy” is a grouping mechanism for some posts (or links or custom post types). Add the following code to your theme’s functions.php file or in a site-specific plugin (recommended) to create a hierarchical custom taxonomy like categories:
Create Taxonomy
- Add and register hierarchical taxonomy
< ?php // hook into the init action and call create_book_taxonomies when it fires add_action( 'init', 'create_book_taxonomies', 0 ); // create two taxonomies, genres and writers for the post type "book" function 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 );
2. Add and register non-hierarchical taxonomy
// 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 ); } ?>
Add Term Meta
1. Register Term meta
< ?php // hook into the init action and call create_book_taxonomies when it fires add_action( 'init', 'create_book_taxonomies', 0 ); // create two taxonomies, genres and writers for the post type "book" function 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 );
2. Add and register non-hierarchical taxonomy
< ?php // hook into the init action and call create_book_taxonomies when it fires add_action( 'init', 'create_book_taxonomies', 0 ); // create two taxonomies, genres and writers for the post type "book" function 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 );
Add Term Meta
1. Register Term meta
add_action( 'init', 'wb_register_term_meta_text' ); function wb_register_term_meta_text() { register_meta( 'term', 'term_meta_text', 'sanitize_term_meta_text' ); }
2. Sanitize data
function sanitize_term_meta_text ( $value ) { return sanitize_text_field ($value); } // GETTER (will be sanitized) function get_term_meta_text( $term_id ) { $value = get_term_meta( $term_id, 'term_meta_text', true ); $value = sanitize_term_meta_text( $value ); return $value; }
3. Add field to category page
add_action( 'writer_add_form_fields', 'wb_add_form_field_term_meta_text' ); function wb_add_form_field_term_meta_text() { ?> < ?php wp_nonce_field( basename( __FILE__ ), 'term_meta_text_nonce' ); ?>< ?php }
4. Add field to category edit page
add_action( 'writer_edit_form_fields', 'edit_form_field_term_meta_text' ); function edit_form_field_term_meta_text( $term ) { $value = get_term_meta_text( $term->term_id ); if ( ! $value ) $value = ""; ?>< ?php } < ?php wp_nonce_field( basename( __FILE__ ), 'term_meta_text_nonce' ); ?>
5. Save Term meta ( on term edit and create )
add_action( 'create_writer', 'save_term_meta_text' ); function ___save_term_meta_text( $term_id ) { // verify the nonce if ( ! isset( $_POST['term_meta_text_nonce'] ) || ! wp_verify_nonce( $_POST['term_meta_text_nonce'], basename( __FILE__ ) ) ) return; $old_value = get_term_meta_text( $term_id ); $new_value = isset( $_POST['term_meta_text'] ) ? sanitize_term_meta_text ( $_POST['term_meta_text'] ) : ''; if ( $old_value && '' === $new_value ) delete_term_meta( $term_id, 'term_meta_text' ); else if ( $old_value !== $new_value ) update_term_meta( $term_id, 'term_meta_text', $new_value ); }
6. Add meta to the list
add_filter( 'manage_edit-writer_columns', 'edit_term_columns', 10, 3 ); function edit_term_columns( $columns ) { $columns['term_meta_text'] = __( 'Custom Term Meta Field', 'text_domain' ); return $columns; }
5. Render metadata on a column
add_filter( 'manage_writer_custom_column', 'manage_term_custom_column', 10, 3 ); function manage_term_custom_column( $out, $column, $term_id ) { if ( 'term_meta_text' === $column ) { $value = get_term_meta_text( $term_id ); if ( ! $value ) $value = ''; $out = sprintf( '%s', esc_attr( $value ) ); } return $out; }