I cannot add a new CSS class to the classes_array array 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.

template.php

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

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

function _bootstrap_gstt_taxonomy_node_get_terms($node, $key = 'tid') {
  static $terms;
  if (!isset($terms[$node-&gt;vid][$key])) {
    $query = db_select('taxonomy_index', 'r');
    $t_alias = $query-&gt;join('taxonomy_term_data', 't', 'r.tid = t.tid');
    $v_alias = $query-&gt;join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
    $query-&gt;fields( $t_alias );
    $query-&gt;condition("r.nid", $node-&gt;nid);
    $result = $query-&gt;execute();
    $terms[$node-&gt;vid][$key] = array();
    foreach ($result as $term) {
      $terms[$node-&gt;vid][$key][$term-&gt;$key] = $term;
    }
  }
  return $terms[$node-&gt;vid][$key];
}


html.tpl.php

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


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?
You simply do as Drupal does in its html.tpl.php file. Instead of using &lt;body&lt;?php print $body_attributes; ?&gt;&gt;, you use the following code.

&lt;body class="&lt;?php print $classes; ?&gt;" &lt;?php print $attributes;?&gt;&gt;


$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-&gt;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-&gt;name. 

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


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

$t_alias = $query-&gt;join('taxonomy_term_data', 't', 'r.tid = %alias.tid');
$query-&gt;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-&gt;join('taxonomy_term_data', 't', "r.$key = %alias.$key");
$query-&gt;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-&gt;join() and use the following code.

$query-&gt;join('taxonomy_term_data', 't', "r.$key = t.$key");
$query-&gt;join('taxonomy_vocabulary', 'v', 't.vid = v.vid');