Dru­pal has a Tax­on­omy mod­ule for cat­e­go­riz­ing con­tent. The mod­ule can gen­er­ate a select box based on the defined tax­on­omy. How­ever, it does not sup­port option groups. I fig­ured I’d share my mod­i­fi­ca­tion for those who’d like to do the same. It was based on code from a Dru­pal forum post which I think was based on Dru­pal 5, not 6.

The code that needs to be mod­i­fied is from _taxonomy_term_select() in modules/taxonomy/taxonomy.module, after line 1032.

function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
  $tree = taxonomy_get_tree($vocabulary_id);
  $options = array();

  if ($blank) {
    $options[''] = $blank;
  if ($tree) {
    $curr_group = '';
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
        if($term->parents[0] == 0) {
          $options[$curr_group] = array();        
        else {
          $choice = new stdClass();
          $choice->option = array($term->tid => str_repeat('-', $term->depth) . $term->name);
          $options[$curr_group][] = $choice;

  return array('#type' => 'select',
    '#title' => $title,
    '#default_value' => $value,
    '#options' => $options,
    '#description' => $description,
    '#multiple' => $multiple,
    '#size' => $multiple ? min(9, count($options)) : 0,
    '#weight' => -15,
    '#theme' => 'taxonomy_term_select',

Essen­tially, the code sim­ply iter­ates through the tree like the orig­i­nal code, except when it encoun­ters a root node it cre­ates a new key with an array value to con­tain the indi­vid­ual options, thereby cre­at­ing an option group using the term’s name as its label. The code isn’t very flex­i­ble since it won’t account for root nodes with no chil­dren. Also it doesn’t account for options with a depth greater than 1, in which case you’d prob­a­bly want to set a class and dis­abled attribute to make it look and act like an option group (since option groups can’t be nested). Such a change would also involve mod­i­fy­ing form_select_options() in includes/form.inc since attrib­utes for option tags is not supported.

Comments are closed.