Author image
Senior Mind

Force the user to select a leaf item in the Drupal taxonomy

Its a tricky Drupal taxonomy problem this one, imagine you have just set up your taxonomy to represent types of web sites:

  <ul>Drupal based Sites
      <li>Drupal based ecommerce</li>
      <li>Standard CMS site</li>
      <li>Social Networking Site</li>
   </ul>

   <ul>Joomla based Sites
      <li>Simple one page site</li>
   </ul>

You set up your node type 'site', and set the vocabulary to apply to it. You create your first site and pop it into the 'Standard CMS site' category, you create another in the 'Drupal based ecommerce category'. Great. But there is a problem - there is nothing stoping you assigning your site to the 'parent' term of Drupal based Sites.

Theres no out of the box solution to this, so the answers lies in a quick module. Follow the steps here (http://drupal.org/node/82926 - until page 2) to create a basic empty new module, and then add the following code - making sure you change YOURMODULE for the name of your module.

function YOURMODULE_nodeapi(&$node,$op,$a3='',$a4=''){
  if ($op=='validate')){
    foreach($node->taxonomy as $vid=>$tid){
      if (intval($tid)){
        $children = taxonomy_get_children($tid,$vid);
        if (count($children)){
          form_set_error('taxonomy]['.$vid,t('Please select another term'));
        }
      }
  }
}

The above code implements hook_nodeapi - this is called whenever changes are made to a node. In our case we are interested in the case of the node being validated. During validation we check each taxonomy term associated with the node (stored in the $node->taxonomy array) to see if it has any children (using the API call taxonomy_get_children). If there are children then we know the user isn't allowed to select the term and so we flag an error (you will probably want to add a more informative message than the basic one in our code)

And that's it - your Drupal nodes should now only be associated with leaf taxonomy terms