Make WordPress Core

Opened 14 years ago

Last modified 3 years ago

#14877 accepted feature request

Ability to create exclusive custom taxonomies

Reported by: benbalter's profile benbalter Owned by: helen's profile 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 12 years ago.
Rough 1st pass -- no JS, no quick-edit
exclusive-taxonomies.php (801 bytes) - added by benbalter 12 years ago.
Plugin to create a radio and dropdown taxonomy with 3 dummy terms
14877.2.diff (4.9 KB) - added by helen 8 years ago.

Download all attachments as: .zip

Change History (64)

#1 @nacin
14 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
14 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
14 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
14 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
14 years ago

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

#6 @johnbillion
14 years ago

  • Cc johnbillion@… added

#7 @nacin
13 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
13 years ago

RE WP_Meta_Box: #15066

#9 @sbressler
13 years ago

  • Cc sbressler@… added

#10 @azizur
13 years ago

  • Cc azizur added

#11 follow-up: @sanchothefat
13 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, $editable = true, $terms ) {

    // add $type to valid taxonomy types

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

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

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


So for post formats you'd have:

    array( 'gallery' => __( 'Gallery' ), 'video' => __( 'Video' ), ...etc... )

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.

Version 0, edited 13 years ago by sanchothefat (next)

#12 @sanchothefat
13 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
13 years ago

  • Cc viper007bond added

#14 @Viper007Bond
13 years ago

  • Cc Viper007Bond added; viper007bond removed

#15 @sidewindernet
13 years ago

  • Cc sidewindernet added

#16 @DrewAPicture
13 years ago

  • Cc xoodrew@… added

#17 @crushlabs
13 years ago

  • Cc crushlabs added

#18 @dwenaus
13 years ago

  • Cc deryk@… added

#19 @webord
12 years ago

  • Cc… added

#20 in reply to: ↑ 11 @husobj
12 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
12 years ago

  • Cc MZAWeb added

#22 @benbalter
12 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
12 years ago

  • Cc jared@… added

12 years ago

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

12 years ago

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

#24 @benbalter
12 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
12 years ago

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

#26 @benbalter
12 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
12 years ago

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

Last edited 12 years ago by scribu (previous) (diff)

#28 @scribu
12 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
12 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
12 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
12 years ago

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

#32 @husobj
12 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
12 years ago

  • Cc dominicparisi@… added

#34 @dominicp
12 years ago

  • Cc dominicparisi@… removed

#35 @bafforosso
12 years ago

  • Cc bafforosso added

#36 @sc0ttkclark
12 years ago

  • Cc lol@… added

#37 @greenshady
12 years ago

  • Cc justin@… added

#38 @trepmal
12 years ago

  • Cc trepmal@… added

#39 @scribu
12 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
12 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
12 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
11 years ago

  • Cc dcowgill@… added

#43 @wonderboymusic
11 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
11 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
11 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
11 years ago

  • Cc desrosj@… added

#47 @hguiney
11 years ago

  • Cc hguiney added

#48 @jfarthing84
11 years ago

  • Cc jeff@… added

#49 @helen
11 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
11 years ago

  • Cc jonathan@… added

#51 @helen
10 years ago

  • Focuses ui added

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

#52 @helen
10 years ago

#27249 was marked as a duplicate.

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

10 years ago

#54 @wonderboymusic
9 years ago

Someone should look at this, could be fun

#55 @Mte90
8 years ago

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

8 years ago

#56 @helen
8 years 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
8 years 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.

8 years ago

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

6 years ago

This ticket was mentioned in Slack in #core-editor by benoitchantre. View the logs.

6 years ago

#61 @mrengy
3 years ago

Looks as though this has been idle for a while. This feature would be really helpful. I came across [this workaround](, but I couldn't get it to work on an attachment (rather than a post).

Note: See TracTickets for help on using tickets.