Changing the <body> element classes in Drupal 7

Drupal has many odd things hard-wired into it. The one I want to get into today is how, in Drupal 7, the <body> element has classes attached to it that sometimes just don’t make sense.

Let’s say you enable a theme, and your <body> element looks like this:

<body class="html front logged-in no-sidebars page-node" >

This happens for me when I have created a new Aurora based sub-theme. The only most of the classes are fine, but the no-sidebars class is the odd duck.

Out of the box, an Aurora theme doesn’t have any regions called sidebar, at all. So, it’s a misnomer to include no-sidebar when it’s not even available to you.

In my case, in my theme, I did end up creating a region called ‘Sidebar’. However, this no-sidebar class was still attached to the <body>. There were certain situations where nothing appeared in this new region, and I wanted to have the correct classes in my markup.

It turns out Drupal is hard-wired to look for the regions “sidebar_first” and “sidebar_second”. This was a common pattern for years in Drupal themes, and I believe was even a recommended best practice.

What I find to be odd, though, is the core CMS thinks to look for these regions. This isn’t some kind of function of any particular core theme. It’s just hard wired into Drupal’s brain.

So, basically, Drupal looks for those two regions, and if it either a) can’t find the regions or b) the regions really do have nothing in them, it adds the no-sidebar class to the <body>.

It also turns out that this is a class that you really can’t change per se, you can only suppress it. How do you do that? Why, a preprocess function in your theme’s template.php file:

    function THEMENAME_preprocess_html(&$vars) {
      //dsm($vars);  //uncomment to get the DSM, check the classes_array
      $vars['classes_array'][3] = '';  //removes less than helpful no-sidebars class that is hard coded into drupal
      //adding theme-specific sidebar indicator class
      if (!empty($vars['page']['REGIONNAME'])) {
         $vars['classes_array'][] = 'THEMENAME-sidebar';
      } else {
         $vars['classes_array'][] = 'THEMENAME-no-sidebar';
      }
    }

All this does is pull apart the classes_array that get attached to your Drupal page. You have to simply set the [3] item to ” to suppress it (unset doesn’t seem to have an effect).

Just swap THEMENAME for, well, your theme’s name, and REGIONNAME for whatever you region you want to evaluate against. In my case, it was “sidebar”.

Now, you can safely theme, knowing that your <body> element has the right classes.