UPDATE 2012-11-11: USE CONTEXT MODULE

I revisit this thread, since I started it, to say to anyone who reads this: Never miiiind.

As Yuri noted elsewhere, the Context Module will do the job.

E.g. for newbies like I were, In Admin /Structure /Context, in a context, I add a "Taxonomy" Condition of tag, "Theater," and set a "Theme HTML" Reaction of three Classes, "centerBody," "centerTitle," and "Midnight." (Midnight style is black bg, light fg; what the other two classes do is a closely-held state secret, as is why we have "theater-style" nodes. ;) ) So, creating a node, in the vocabulary field named "Style," I select the term "Theater," and Context will add the three desired classes to the Body tag.

This one-tag-to-one-or-more-classes ability, along with being able to set other conditions and reactions at the same time means Context is inexpressibly better than the mod posted here. I took this long to revisit this thread partly because I was so busy applying Context and unplugging my kludge....

Thanks to Yuri for suggesting Context, and also [can't remember name] who first suggested "context" long before I realized that meant a module.

END EDIT, IGNORE THE REST! :/

General idea:
Add class, based on a specific vocabulary's term, to a node's body tag.

Background:
We use D7 with a Zen sub-theme.

Detail:
We have a vocabulary called Album.
Album vocabulary is added to some (but not all) content types.
Album vocabulary is set for only one term per node, required.
We want to add that term as a class in the Body tag, for example the form "album-[tid]".

EDIT: See this message for code that works to add a body class for a particular vocabulary's terms in a page.

Apology:
I have researched this, and found other folks wanting to, or trying to, add taxonomy terms as classes to the Body tag. What we want seems do-able. We're not expert at Drupal or PHP, but we're smart enough :) to figure it out, given enough hints.

Studying these messages for hints:
1072806: Drupal 7 Adding body class or ID based on Taxonomy term
stackoverflow.com: How to add a body class for the current node's taxonomy to a Drupal 7 theme"

In a comment on 1072806, agoradesign says "As this function prints all used taxonomy terms of any vocabulary used by the node, you would have to add an extra query condition, if you only want to print terms of a particular vocabulary id." Yah! That's what we're looking for!

We tried the stackoverflow method, and implemented it (we think) pretty much as described. The code below was placed in in sites/all/themes/OURTHEMENAME/template.php. Note that "field_collection" was substituted for "field_tags" because "collection" is the machine name for the Album vocabulary, but we tried both collection and tags. No test was added to make sure we had the right content type (one that had the Album vocabulary field). Anyway, as far as we could tell, after much hammering and tweaking, the function just wasn't firing! Another morning shot to heck. Any clues? Any help? Anyone?

/**
 * Override or insert variables into the html template.
 *
 * @param $vars
 *   An array of variables to pass to the theme template.
 * @param $hook
 *   The name of the template being rendered ("html" in this case.)
 */
function OURTHEMENAME_preprocess_html(&$vars, $hook) {
  // If the user is silly and enables zen as the theme, add some styles.
  if ($GLOBALS['theme'] == 'zen') {
    include_once './' . drupal_get_path('theme', 'zen') . '/zen-internals/template.zen.inc';
    _zen_preprocess_html($vars, $hook);
  }

  // Classes for body element. Allows advanced theming based on context
  // (home page, node of certain type, etc.)
  if (!$vars['is_front']) {
    // Add unique class for each page.
    $path = drupal_get_path_alias($_GET['q']);
    // Add unique class for each website section.
    list($section, ) = explode('/', $path, 2);
    if (arg(0) == 'node') {
      if (arg(1) == 'add') {
        $section = 'node-add';
      }
      elseif (is_numeric(arg(1)) && (arg(2) == 'edit' || arg(2) == 'delete')) {
        $section = 'node-' . arg(2);
      }
      // Modification to add field_collection taxonomy term id to body tag class begins here
      $node = node_load(arg(1));
      $results = field_view_field('node', $node, 'field_collection', array('default'));
      foreach ($results as $key => $result) {
        if (is_numeric($key)) {
          // Add taxonomy ID. 
          $vars['classes_array'][] = "album-id-" . $result['#options']['entity']->tid  ;
        }
      }
      // Modification ends here
    }
    $vars['classes_array'][] = drupal_html_class('section-' . $section);
  }
  if (theme_get_setting('zen_wireframes')) {
    $vars['classes_array'][] = 'with-wireframes'; // Optionally add the wireframes style.
  }
  // Store the menu item since it has some useful information.
  $vars['menu_item'] = menu_get_item();
  switch ($vars['menu_item']['page_callback']) {
    case 'views_page':
      // Is this a Views page?
      $vars['classes_array'][] = 'page-views';
      break;
    case 'page_manager_page_execute':
    case 'page_manager_node_view':
    case 'page_manager_contact_site':
      // Is this a Panels page?
      $vars['classes_array'][] = 'page-panels';
      break;
  }
}

Comments

harriszrashid’s picture

Hi Irwin,

This was something that was very easy to do in Drupal 6, but unfortunately becomes a little more complicated in Drupal 7.

I admit, I have not tested this method, but was curious about it when I saw your question.

Take a look at this thread, which I think has a solution to your problem.

http://drupal.org/node/1072806

Let me know if it doesn't work out for you.

Thanks,

Harris.

irwin nerwin’s picture

Thanks, Harris, for getting me to take another look at http://drupal.org/node/1072806. First I used this code as posted by marblegravy, which put all taxonomy terms in the BODY tag. Riffing off a suggestion he made, I modified the code as described in my comment, and managed to get it limited to just the one-word-per-node taxonomy class I wanted.

Dogbert waggy-tail victory dance

kdmarks’s picture

This was just what I needed. Added the node tax term to the body as a class. Perfect! Thanks for sharing.

knalstaaf’s picture

This worked pretty much out of the box:

In your template.php

function MYTHEME_preprocess_html(&$variables) {
  if(arg(0)=='node' && is_numeric(arg(1))) {
    $node = node_load(arg(1));  
    $results = _MYTHEME_taxonomy_node_get_terms($node); 
    if(is_array($results)) {
      foreach ($results as $item) { 
        $variables['classes_array'][] = "taxonomy-".strtolower(drupal_clean_css_identifier($item->name));
      }
    }
  }
}
 
function _MYTHEME_taxonomy_node_get_terms($node, $key = 'tid') {
  static $terms;
  if (!isset($terms[$node->vid][$key])) {
    $query = db_select('taxonomy_index', 'r');
    $t_alias = $query->join('taxonomy_term_data', 't', 'r.tid = t.tid');
    $v_alias = $query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
    $query->fields( $t_alias );
    $query->condition("r.nid", $node->nid);
    $result = $query->execute();
    $terms[$node->vid][$key] = array();
    foreach ($result as $term) {
      $terms[$node->vid][$key][$term->$key] = $term;
    }
  }
  return $terms[$node->vid][$key];
}

This will display term names of every term related to the node. If you'd prefer term ID's instead of names as classes, replace $item->name with $item->tid (around line 7 of this code).

(Source)