As most of you would have already know, WordPress by default provides two built-in taxonomies – Categories and Tags. If you need to create a new association, then it is also very easy to create custom taxonomies in WordPress.
But one of the major limitations while creating custom taxonomies in WordPress is that you can’t make them as “single select”. By “single select” I mean the ability to restrict only one term to be selected for a post.
Following in one example where you might need this ability. Let’s say you are storing movie information in a custom post type and you need to store the PG rating for the movie in a custom taxonomy. Each movie will have only one rating and you should restrict that only one rating term is stored for a movie.
Recently I faced a similar scenario and this post talks about how I solved it.
Default Taxonomy types in WordPress
WordPress by default supports only two types of taxonomies.
- Hierarchical taxonomies, which are like categories. You can have multiple hierarchies and they are rendered using checkboxes.
- Non Hierarchical taxonomies, which are like tags. Here you create specify a list of comma separated taxonomy terms for a post.
As you might have already noted, in both the above two types you can’t restrict a post to have only one term selected from a given taxonomy.
Custom Field vs Custom Taxonomy
One option to solve this issue is to create a custom meta box and store the information in custom field.
This approach allows you to create your own UI, but if you need to retrieve posts based on the value in the field then you have to query your posts based on meta data which is generally slower than retrieving posts based on taxonomies.
Convert taxonomies into single select
The approach that I took to solve this problem is to create a custom meta box to display the taxonomies as radio buttons and then save the terms to the post as taxonomies when the post is saved.
Using a custom meta box to display the taxonomy
We can use a custom meta box for displaying the taxonomy instead of the built-in one by specifying the function that prints the meta box to the
meta_box_cb options of the
args parameter that is passed to the
And then inside the function we can fetch the term that is associated with the post and then display the radio buttons (or a dropdown).
Saving the term to the taxonomy
Now when a user saves the post, we can hook into the
save_post hook and then save the term as part of the taxonomy for that post.
Making sure the term is selected
If the term is mandatory then we can also send a error message back to the user (and change the post to draft) using the
edit_form_top hook if the user has not selected at least one term.
The entire source code is available as a gist. The code can be either added to your theme’s
functions.php file or as a separate plugin. Make sure you use the correct taxonomy name when you use this code.
- WordPress Developer tools to increase productivity in WordCamp Mumbai
- Email Log WordPress plugin v1.9.1 released
- Email Log WordPress plugin v1.9 released
- How to find if you are on the last page of a multi-page post in WordPress
- Easy Retweet WordPress plugin v3.1 Released
- Creating custom tables with correct Character Set and Collation in WordPress
Thank you for writing this post, it really helped me transform the checkboxes into select drop-downs.
I am glad to know that it was useful to you.
Thanks for this great tip!
Adding a little improvement, if you name your input field “tax_input[movie_rating]” (movie_rating being your taxonomy name) and set the value to term name, then you won’t have to implement any hook to save the value. It will be saved automatically. At least it works in WP 4.4.
In case of a hierarchical taxonomy, the input name should have additional braces (tax_input[movie_rating]) and its value should be term id instead of term name. And then of course the checked input logic will also have to use the id instead of the name.
Thanks a lot for the excellent piece of code! Works like charm! Always wanted to use my custom taxonomies like that 🙂
Glad to know that you found it useful.
Thanks a lot!
Thank you for this code , it’s really beneficial, but how can i make it work with ACF ( advanced custom
My website has so many taxonomy, can you help me show only one taxonomy selected on wp admin edit post ?
current I set hidden taxonomy with show_ui is false
register_taxonomy(‘developer’, ‘post’, array(
‘hierarchical’ => true,
‘labels’ => $labels, /* NOTICE: Here is where the $labels variable is used */
‘show_ui’ => FALSE,
‘query_var’ => true,
‘rewrite’ => array(‘slug’ => ‘developer’),
You are saving the “name” of the term as the value of the select, and them searching for it by name on the server side.
you could just
value=”term_id ); ?>”
value=”name ); ?>”
and then you can save the ID directly.
This is great, thanks.
The only problem I’m having is that the post is publishing even if I don’t select a tax.
I get the error telling me it needs to be selected, but the post status still sets to published.
How comes and how do I keep it as Draft if its not selected?
Is there any solution to this?
Thankx alot for great tips.
Unfortunately this no longer display the meta box in gutenberg – looking for a solution!
Noting that the code in this article uses esc_attr_e to escape and echo dynamic values, but this is incorrect. esc_attr_e is a localisation function. esc_attr_e and esc_html_e are not shorthand for echo esc_attr, they’re short for echo esc_attr( __( and echo esc_html( __(
This means that if your value matches a translated string it could be translated into another language by accident.
Instead the correct thing to do is echo esc_attr( and echo esc_html(