WordPress Custom Taxonomies
Categories and tags are the built in taxonomies. With register_taxonomy() you can create your own grouping, like Genre for books, Brand for products or Location for events. If it is hierarchical it works like categories, and if not it works like tags.
Register a taxonomy for a post type
<?php
/**
* Plugin Name: Books
*/
add_action( 'init', function () {
register_post_type( 'book', array(
'labels' => array( 'name' => 'Books', 'singular_name' => 'Book' ),
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
'supports' => array( 'title', 'editor' ),
) );
register_taxonomy( 'genre', array( 'book' ), array(
'labels' => array( 'name' => 'Genres', 'singular_name' => 'Genre' ),
'hierarchical' => true,
'public' => true,
'show_admin_column' => true,
'show_in_rest' => true,
'rewrite' => array( 'slug' => 'genre' ),
) );
} );
The first parameter is the taxonomy name (genre), the second is the list of post types that can use it, and the third holds the options.
$ wp plugin activate tc-books
Plugin 'tc-books' activated.
Success: Activated 1 of 1 plugins.
$ wp taxonomy list –object_type=book –fields=name,label,hierarchical
name label hierarchical
genre Genres 1
$ wp term create genre "Fiction" –slug=fiction –porcelain
2
$ wp term create genre "Fantasy" –slug=fantasy –parent=2 –porcelain
3
$ wp post create –post_type=book –post_title="The Alchemist" –post_status=publish –porcelain
5
$ wp post term add 5 genre fiction
Success: Added term.
$ wp term list genre –fields=term_id,name,slug,parent,count
term_id name slug parent count
3 Fantasy fantasy 2 0
2 Fiction fiction 0 1
Options of register_taxonomy()
| Option | Meaning |
|---|---|
| hierarchical | true: like categories (with parents). false: like tags |
| public | Visible on the front end and in the dashboard |
| show_admin_column | Show the terms as a column in the posts list |
| show_in_rest | Needed for the block editor and REST API |
| rewrite | The URL base of the term pages |
| labels | Texts in the dashboard |
Archive page and queries
$ curl -s -o /dev/null -w "%{http_code}\n" http://example.com/genre/fiction/
404
$ wp rewrite flush
Success: Rewrite rules flushed.
$ curl -s -o /dev/null -w "%{http_code}\n" http://example.com/genre/fiction/
200
The first answer is 404. WordPress did not know the new URL rule yet. After wp rewrite flush (the same as saving Settings > Permalinks) the page works. In a real plugin, flush the rules once in the activation hook, like we did in the Custom Post Types chapter.
Use tax_query to get posts by a custom taxonomy:
$q = new WP_Query( array(
'post_type' => 'book',
'tax_query' => array(
array( 'taxonomy' => 'genre', 'field' => 'slug', 'terms' => 'fiction' ),
),
) );
foreach ( $q->posts as $p ) {
echo $p->post_title . ' => ' . implode( ', ', wp_get_post_terms( $p->ID, 'genre', array( 'fields' => 'names' ) ) ) . "\n";
}
The Alchemist => Fiction
Useful functions
get_the_terms( $post_id, 'genre' ): terms of a post.get_terms( array( 'taxonomy' => 'genre' ) ): list all terms.the_terms( $post_id, 'genre', 'Genre: ', ', ' ): print terms as links.wp_set_object_terms( $post_id, 'fiction', 'genre' ): set terms from code.
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |