I'm using Drupal 7, and a Bootstrap sub-theme. I am using the following code to add a new CSS class (taxonomy-[vocabulary-name]) to the classes_array array.


function bootstrap_gstt_preprocess_html(&$variables) {
  if (arg(0) == 'node' && is_numeric(arg(1))) {
    $node = node_load(arg(1));  
    $results = _bootstrap_gstt_taxonomy_node_get_terms($node); 
    $taxonomy_vocab = $results->name;
    if (is_array($results)) {
      foreach ($results as $item) {
        $taxonomy_vocab = "taxonomy-".strtolower(drupal_clean_css_identifier($item->name)); 
        $variables['classes_array'][] = $taxonomy_vocab;

        $variables['classes'] = implode(' ', $variables['classes_array']);

function _bootstrap_gstt_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];


<!DOCTYPE html>
<html<?php print $html_attributes;?><?php print $rdf_namespaces;?>>
  <link rel="profile" href="<?php print $grddl_profile; ?>" />
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <?php print $head; ?>
  <title><?php print $head_title; ?></title>
  <?php print $styles; ?>
  <!-- HTML5 element support for IE6-8 -->
  <!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <?php print $scripts; ?>
<body<?php print $body_attributes; ?>>
  <div id="skip-link">
    <a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
  <?php print $page_top; ?>
  <?php print $page; ?>
  <?php print $page_bottom; ?>

With dpm($variables['classes_array']);, the new CSS classes I added appear in the array, but they aren't output as body CSS classes.

Is there anything I need to change in my code?

  • what's code in file html.tpl.php ?
    – MrD
    Commented Sep 5, 2016 at 15:37
  • I'm voting to close this question as off-topic because it's been cross-posted on Stack Overflow. Please post a question to one site in the network only.
    – Clive
    Commented Sep 5, 2016 at 15:38
  • Clive - I'll remove it from the other stack overflow as this site is more relevant
    – wotney
    Commented Sep 5, 2016 at 16:20
  • Sounds good - while you're there, probably a good idea to add some more details. It isn't answerable at the moment, but probably will be if you edit the post and include the full preprocessing function (including signature), and details of what theme/base theme you're using
    – Clive
    Commented Sep 5, 2016 at 16:25
  • Clive - I can't seem to be able to delete my question on the other network :/
    – wotney
    Commented Sep 5, 2016 at 16:58

1 Answer 1


You simply do as Drupal does in its html.tpl.php file. Instead of using <body<?php print $body_attributes; ?>>, you use the following code.

<body class="<?php print $classes; ?>" <?php print $attributes;?>>

$attributes is set from template_preprocess() with the following code.

  // Flatten out attributes, title_attributes, and content_attributes.
  // Because this function can be called very often, and often with empty
  // attributes, optimize performance by only calling drupal_attributes() if
  // necessary.
  $variables['attributes'] = $variables['attributes_array'] ? drupal_attributes($variables['attributes_array']) : '';
  $variables['title_attributes'] = $variables['title_attributes_array'] ? drupal_attributes($variables['title_attributes_array']) : '';
  $variables['content_attributes'] = $variables['content_attributes_array'] ? drupal_attributes($variables['content_attributes_array']) : '';

Also, you don't need the following line in bootstrap_gstt_preprocess_html().

$variables['classes'] = implode(' ', $variables['classes_array']);

template_process(), which is executed after bootstrap_gstt_preprocess_html(), contains the following code.

  // Flatten out classes.
  $variables['classes'] = implode(' ', $variables['classes_array']); 

So, what your code is doing is already done from Drupal.

As side note, this what I would change in the code you shown.

$results = _bootstrap_gstt_taxonomy_node_get_terms($node); 
$taxonomy_vocab = $results->name;
if (is_array($results)) {
  // Omissis.

Since _bootstrap_gstt_taxonomy_node_get_terms() is surely returning an array, you cannot access an object property as you do with $results->name.

$t_alias = $query->join('taxonomy_term_data', 't', 'r.tid = t.tid');
$v_alias = $query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');

If you are going to use the value returned from $query->join(), then you should use the following code.

$t_alias = $query->join('taxonomy_term_data', 't', 'r.tid = %alias.tid');
$query->join('taxonomy_vocabulary', 'v', "$t_alias.vid = %alias.vid");

Also, since you are using $key (whose default value is 'tid') in the rest of the code, you should probably use the following code.

$t_alias = $query->join('taxonomy_term_data', 't', "r.$key = %alias.$key");
$query->join('taxonomy_vocabulary', 'v', "$t_alias.vid = %alias.vid");

To understand what %alias means, see SelectQuery::join().

$condition: The condition on which to join this table. If the join requires values, this clause should use a named placeholder and the value or values to insert should be passed in the 4th parameter. For the first table joined on a query, this value is ignored as the first table is taken as the base table. The token %alias can be used in this string to be replaced with the actual alias. This is useful when $alias is modified by the database system, for example, when joining the same table more than once.

If you are sure the same table is not joined more than once, you can simply ignore the value returned from $query->join() and use the following code.

$query->join('taxonomy_term_data', 't', "r.$key = t.$key");
$query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
  • A fantastic, detailed reply - thanks for your time and effort. It really is appreciated
    – wotney
    Commented Sep 6, 2016 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.