Make WordPress Core

Opened 7 years ago

Last modified 11 months ago

#14877 accepted feature request

Ability to create exclusive custom taxonomies

Reported by: benbalter Owned by: helen
Milestone: Future Release Priority: normal
Severity: minor Version:
Component: Taxonomy Keywords: needs-patch
Focuses: ui Cc:


Custom taxonomies should have the option of toggling exclusivity, meaning the user should only be able to select one term at a time.

Currently, developers wishing to implement an exclusive custom taxonomy (and thus would prefer radio buttons rather than check boxes on the add/edit post pages) must remove the existing taxonomy meta box completely and build their own, simply to change the input type. This not only duplicates code and development effort, but has the potential to create security vulnerabilities when plugin developers stray from best practices, for example, when recreating the AJAX add term functionality.

Exclusive taxonomies are not uncommon in every day life and are even more common when one thinks about typical custom post type implementations (e.g., students->school year, employee->department, car->color, ice cream->flavor).

While the best implementation is uncertain, I propose the function register_taxonomy accept an optional 'exclusive' argument (similar to 'hierarchical') that would change the check boxes within the taxonomy meta box to radio buttons and would handle the POST accordingly.

Attachments (3)

14877.diff (28.6 KB) - added by benbalter 5 years ago.
Rough 1st pass -- no JS, no quick-edit
exclusive-taxonomies.php (801 bytes) - added by benbalter 5 years ago.
Plugin to create a radio and dropdown taxonomy with 3 dummy terms
14877.2.diff (4.9 KB) - added by helen 11 months ago.

Download all attachments as: .zip

Change History (61)

#1 @nacin
7 years ago

  • Keywords custom taxonmy removed
  • Type changed from enhancement to feature request

I see use cases for this, for sure. We've discussed radio buttons in the context of #14746.

We have checkboxes for the hierarchical meta box only, with the nonhierarchical taxonomies receiving the ad hoc tags box.

How would you handle hierarchy? Would "exclusive" be limited to nonhierarchical taxonomies using a derivative of the hierarchical meta box? Is hierarchy and exclusive .. mutually exclusive?

When I first saw this, my initial thought was that "exclusive" should be solely a property of the meta box, but obviously we would have to enforce that elsewhere, on save.

I think deciding on exactly how it should be enabled and enforced is the tricky part. The code should be easy.

#2 @thenbrent
7 years ago

My use case for this is a rating taxonomy (Excellent, Good, Satisfactory, Below Average, Poor). This needs exclusive types as an item can't be both "Excellent" & "Satisfactory".

However, there might be multiple dimensions each requiring an individual rating - 'Speed', 'Service, 'Quality' etc. These could be separated into distinct meta boxes or combined into the one hierarchy. If in the one hierarchy, it would need to be possible to choose one rating (child) for each dimension (parent). The advantage of this method being that it uses one meta box instead of three.

Unfortunately, these are probably atypical requirements. For most use cases, I imagine exclusive means on that taxonomy in it's entirety. So, I guess that would be the better option and I'll be left with 3 meta boxes. :)

#3 @scribu
7 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Just having an 'exclusive' flag is kind of useless, since most use cases will also require defining a custom metabox.

We already have two distinct capabilites - 'assign_terms' and 'manage_terms' - which can be used to define exclusive taxonomies.

#4 @nacin
7 years ago

  • Milestone set to Future Release
  • Resolution wontfix deleted
  • Status changed from closed to reopened

Reopening as I plan to take this in a modified direction. Will follow up.

#5 @nacin
7 years ago

  • Owner set to nacin
  • Status changed from reopened to reviewing

#6 @johnbillion
7 years ago

  • Cc johnbillion@… added

#7 @nacin
6 years ago

#16708 marked as a duplicate.

Here's what I'm planning here. Basically, a taxonomy will be able to choose from a series of meta boxes.

  • checkboxes (currently used for hierarchical taxonomies)
  • input box (currently used for non-hierarchical taxonomies)
  • radio buttons, based on the current checkbox meta box (exclusive)
  • radio buttons, based on the current post format meta box (exclusive)
  • a dropdown (exclusive)

There are possibly others, especially hybrids (like the current non-hierarchical taxonomy box, only with a dropdown, like the current Trac keywords box). Also possibly one other that escapes me, but I think I got the main ones covered. I'm not even covering sortable term orders here, which is a whole other idea.

Exclusive taxonomies (where you can enforce only one term being selected) will be enforced server-side. The post format stuff will be entirely abstracted into one of these meta boxes as well as the save handler.

This will also allow us to adopt a flag to turn off the popular terms support, particularly the functionality in #3130, making the existing hierarchical taxonomy box far more flexible. There will also be a flag, where appropriate, for the option to choose no term, in the case of exclusive taxonomies (otherwise you couldn't de-select the choice). There can also be a flag for the ability to add new terms (possibly based on permissions), the tag cloud as appropriate, etc etc.

I think this is also a perfect time to finally create a basic WP_Meta_Box class.

This (as well as the class) is something I'm willing to shepherd for 3.2. Support it during the scope sessions if you like it.

The ideas here have been bounced around a bit among other members of the core team (at Tybee), but I'd like to see where else this can go to grow a new API.

#8 @scribu
6 years ago

RE WP_Meta_Box: #15066

#9 @sbressler
6 years ago

  • Cc sbressler@… added

#10 @azizur
6 years ago

  • Cc azizur added

#11 follow-up: @sanchothefat
6 years ago

  • Cc sanchothefat added

This is something I really really wanna see in core.

Just my thoughts on the initial post here:

Where we have 'heirarchical' => true it would make more sense to me to have a 'type' argument which would accept one of:

  • heirarchical
  • exclusive
  • flat

My reasoning here is that an exclusive taxonomy could not be heirarchical. If it's one term it shouldn't be in another. The value 'flat' would equate to the tag style taxonomy.

There's another benefit to this approach which is that core methods could be added to register valid taxonomy types. The register_taxonomy_type function would take the type id and a callback function for the metabox. It'd be a neater solution to creating custom taxonomy meta boxes as well.

An example pseudocode function:

register_taxonomy_type( $type, $meta_box ) {

    // add $type to valid taxonomy types

    // associate the meta box callback function with the $type


So for the exclusive type you'd have:


With regards to backwards compatibility it would simply be a case of if the 'type' argument is not present the 'heirarchical' boolean is mapped to the 'heirarchical' or 'flat' taxonomy types.

This is probably what you had in mind already but wanted to get my ideas down in the appropriate place.

You would need to extend register_taxonomy() to accept two more arguments:

editable = boolean

if $editable is false then don't show 'add new' links or main admin UI and rescind manage_terms capabilities

terms = array

if $terms is supplied these would be the default terms in the taxonomy. $terms should be required when $editable is false

Last edited 6 years ago by sanchothefat (previous) (diff)

#12 @sanchothefat
6 years ago

Regarding the above you'd also have to be able to specify the save routine, probably in the register_taxonomy_type() bit. That would allow for having a dropdown style interface that could use the same saving routine as the radio button style exclusive type.

#13 @Viper007Bond
6 years ago

  • Cc viper007bond added

#14 @Viper007Bond
6 years ago

  • Cc Viper007Bond added; viper007bond removed

#15 @sidewindernet
6 years ago

  • Cc sidewindernet added

#16 @DrewAPicture
6 years ago

  • Cc xoodrew@… added

#17 @crushlabs
6 years ago

  • Cc crushlabs added

#18 @dwenaus
6 years ago

  • Cc deryk@… added

#19 @webord
5 years ago

  • Cc webord.net@… added

#20 in reply to: ↑ 11 @husobj
5 years ago

  • Cc ben@… added

I agree with Nacin's initial list of UI options you may want to use.

Replying to sanchothefat:

Where we have 'heirarchical' => true it would make more sense to me to have a 'type' argument which would accept one of:

  • heirarchical
  • exclusive
  • flat

My reasoning here is that an exclusive taxonomy could not be heirarchical. If it's one term it shouldn't be in another. The value 'flat' would equate to the tag style taxonomy.

I think you may want to have an exclusive hierarchical taxonomy. An example might be an employee > job title relationship where an employee can only be in one department, but job titles are hierarchical to denote structure within a company.

#21 @MZAWeb
5 years ago

  • Cc MZAWeb added

#22 @benbalter
5 years ago

Agree with husobj that exclusive hierarchical taxonomies are possible (think organizing a patches CPT by WP version #, you'd have 3.2 as a top level term, and under that 3.2.1, 3.2.2, etc.).

Following up on the progress of #18179 per nacin's comment, it looks like the direction WP_Meta_Box went may make this easier in the long run, but in the near term doesn't natively support anything approaching the UI described.

Glad to take a first pass at this, to move things along, and if WP_Meta_Boxes becomes core, shouldn't be too hard to incorporate.

Either way, it sounds like the general consensus is adding an input to the register_post_type() args array, to accept check, input, radio, or dropdown?

#23 @jaredatch
5 years ago

  • Cc jared@… added

5 years ago

Rough 1st pass -- no JS, no quick-edit

5 years ago

Plugin to create a radio and dropdown taxonomy with 3 dummy terms

#24 @benbalter
5 years ago

  • Keywords has-patch dev-feedback added

Uploaded 14877.diff which is an extremely rough first pass, but should at least help get things going. I tried to write it in such a way that could easily be converted over to class that extends WP_Meta_Box down the line. AJax adding of new terms isn't done yet, as is a quick-edit UI similarly lacking, but the basic concept/proposed approach/functionality is there.

I abstracted the native category and tags drop downs, and attached a plugin ( exclusive-taxonomies.php ) that creates a radio and dropdown taxonomy for testing purposes.

I can keep plugging away, but thought I'd check in before I went too far down the rabbit hole.

#25 follow-up: @scribu
5 years ago

Why do we need both 'dropdown' and 'radio'?

#26 @benbalter
5 years ago

Hadn't thought of it when I originally opened the ticket, and was just going off of Nacin's specs above. Easy to code (just spits out wp_dropdown_categories()), and I assume you'd use it for the same reason you'd use a dropdown vs. radio buttons anyplace else (sequential stuff like year of birth, state, etc.)?

#27 @scribu
5 years ago

I assume you'd use it for the same reason you'd use a dropdown vs. radio buttons anyplace else (sequential stuff like year of birth, state, etc.)?

I don't follow. You can order radio buttons just as well as options in a dropdown.

Version 0, edited 5 years ago by scribu (next)

#28 @scribu
5 years ago

Also, if you would want to save space, you would want to put multiple taxonomy dropdowns in a single metabox, which is outside the scope of this ticket.

#29 @benbalter
5 years ago

Replying to scribu:

I don't follow. You can order radio buttons just as well as options in a dropdown.

Sorry, meant I assume the logic would be to give developers the option to use either a dropdown or radios... the same decision they'd make anyplace else on the internet. Not sure what the rule/design decision is there, but, e.g., I've never seen year of birth or states represented with radio buttons. Again, was just going off of the comments above and since it's modular, easy to just pull out that one function if need be for simplicity sake.

#30 in reply to: ↑ 25 @nacin
5 years ago

Replying to scribu:

Why do we need both 'dropdown' and 'radio'?

Why not? Perhaps there are are expected to be dozens of items, or 3 items. One might want dropdowns in one case but radio buttons in another.

Why do both <input type="radio"> and <select> both exist? In both cases, the end result is take X items, pick one. It's because they have different user interface and experience uses.

#31 @Viper007Bond
5 years ago

+1 to both. If you have three items, radio is easiest. If you have 100, dropdown is a must.

#32 @husobj
5 years ago

+1 to both input styles from me too.

Radio buttons work well for a short set of options like post formats.

Dropdrown menu would be better if you had a big list of countries etc.

#33 @dominicp
5 years ago

  • Cc dominicparisi@… added

#34 @dominicp
5 years ago

  • Cc dominicparisi@… removed

#35 @bafforosso
5 years ago

  • Cc bafforosso added

#36 @sc0ttkclark
5 years ago

  • Cc lol@… added

#37 @greenshady
5 years ago

  • Cc justin@… added

#38 @trepmal
5 years ago

  • Cc trepmal@… added

#39 @scribu
5 years ago

It turns out that exclusivity can also depend on the post type.

For example, you might want to be able to select a single category for a post, but multiple categories for a page.

#40 follow-up: @scribu
5 years ago

So, the appropriate API would be something like this:

register_taxonomy_for_object_type( 'category', 'page', 'exclusive' );

Of course, things are complicated by the fact that register_taxonomy() demands an object type as well.

#41 in reply to: ↑ 40 @MikeSchinkel
5 years ago

  • Cc mike@… added

Replying to scribu:

If you are going to add an occassionally used parameter it would be better as part of an $args array in case other parameters are ever needed which follows other register_*() function signature patterns:

register_taxonomy_for_object_type( 'category', 'page', array( 'exclusive' => true ) );

#42 @dcowgill
4 years ago

  • Cc dcowgill@… added

#43 @wonderboymusic
4 years ago

  • Keywords needs-refresh added; dev-feedback removed

#14206 was moved to 3.7 and provides meta_box_callback as an arg to register_taxonomy() - seems like a new core meta box callback function could go a long way here?

This patch currently explodes against trunk, as expected

#44 @helen
4 years ago

I'm down with a few other core callback functions - radio, select, maaaaybe multi-select (horrible UX by default, but can be used with JS helpers). I don't see why checkboxes and input+suggest shouldn't also be choices for any taxonomy, hierarchical or not. Just have to do the right thing with ID vs. slug.

#45 @helen
4 years ago

  • Milestone changed from Future Release to 3.7

Actually, I'm so down with it, I said so at WCSF and now I'm moving this to 3.7.

#46 @desrosj
4 years ago

  • Cc desrosj@… added

#47 @hguiney
4 years ago

  • Cc hguiney added

#48 @jfarthing84
4 years ago

  • Cc jeff@… added

#49 @helen
4 years ago

  • Keywords needs-patch added; has-patch needs-refresh removed
  • Milestone changed from 3.7 to Future Release

Sad - gotta punt for now. Suggest that a patch do the following:

  • Allows the current post_categories_meta_box and post_tags_meta_box to be used for both hierarchical and non-hierarchical taxonomies. Former expects IDs for save, latter expects slugs. This is probably going to take some running around inside other functions as well.
  • Adds callback functions for radio, select, and multi-select.

This is operating on the assumption that #14206 will be landing in 3.7 shortly, adding the meta_box_cb arg to register_taxonomy().

#50 @jchristopher
4 years ago

  • Cc jonathan@… added

#51 @helen
3 years ago

  • Focuses ui added

benbalter noted it way early on, but let's not forget to include inline edit. Related: #26948

#52 @helen
3 years ago

#27249 was marked as a duplicate.

This ticket was mentioned in IRC in #wordpress-dev by rickalee. View the logs.

3 years ago

#54 @wonderboymusic
2 years ago

Someone should look at this, could be fun

#55 @Mte90
11 months ago

I tried to refresh the patch but few things in the core are changed so require a check before try to refresh.

11 months ago

#56 @helen
11 months ago

I wanted to actually write some code for once, so 14877.2.diff is a fresh start that has an initial setup for a select dropdown. It works, but does not include "Add New" functionality. Much of the naming and markup are just to get something going and don't have to stay the same, and there are also a few todos in there.

I may not come back to this immediately, so if somebody else wants to continue from here, pipe up so we don't duplicate efforts. What I wrote in 49 mostly still holds true, except let's not chase multi-select just yet since default multi-select UI is terrible and the resulting data is no different from checkboxes.

#57 @helen
11 months ago

  • Owner changed from nacin to helen
  • Status changed from reviewing to accepted

This ticket was mentioned in Slack in #core by helen. View the logs.

11 months ago

Note: See TracTickets for help on using tickets.