Skip to main content
  • Home
  • Work
  • Photography
  • Contact
  • Client Login
New Rivers Digital
Home Blogs Eric Weik's blog

Use THEME_preprocess_page() to add a "subsection" body class.

In:
  • Drupal Recipes
  • Theming
  • Zen
  • Zen Theming
1Sep2009

The Zen Theme for Drupal is a great place to start building a standards-compliant Drupal site. One of the useful features of Zen for site design is the fact that it adds multiple classes to the document body (in addition to the classes already added by Drupal core). But if these classes are not enough, we can easily add more through THEME_preprocess_page().

By default, Zen uses the URL path to create "section" and "page" classes which are added as to the body tag. Take for example, the hypothetical page: site.com/spectrum/red the body tag would include the classes:

  • page-spectrum-red
  • section-spectrum

In most cases this is sufficient to craft CSS selectors to style a specific page, or collection of pages within a section. However, what about the case where content is buried deeper? For example, imagine these urls:

  • site.com/spectrum/visible/orange
  • site.com/spectrum/visible/yellow
  • site.com/spectrum/ultraviolet/90nm

It would be nice to be able to able to add a selector to style all of the pages in the "visible" subsection differently than those in the "ultraviolet" subsection. Lets imagine that for site.com/spectrum/visible/orange, the the following selectors were available to us:

  • page-spectrum-orange
  • section-spectrum
  • subsection-visible

We can do this by implementing hook_preprocess_page() in template.php, with the following (where THEME is the id of our theme):

<?php
/**
* Override or insert variables into the page templates.
*
* NRD: Output body a body class based on the "subsection" which works
*      much like the default Zen "section" body class. 
*      E.g.: /section0/subsection1/page2 =>
*            section-section0
*            subsection-subsection1
*
* @param $vars
*   An array of variables to pass to the theme template.
* @param $hook
*   The name of the template being rendered ("page" in this case.)
*/
function zen_THEME_preprocess_page(&$vars, $hook) {
 
// Add unique class for each subsection (e.g. /section0/subsection1/page2
 
$path = drupal_get_path_alias($_GET['q']);
 
$sections = explode('/', $path,3);
 
 
// If subsection *and* page are defined
 
if ($sections[1] && $sections[2]) {
   
$classes[] = zen_id_safe('subsection-' . $sections[1]);
  }

 

// Add classes to body 
 
$vars['body_classes_array'] = $classes;
 
$vars['body_classes'] = implode(' ', $classes); // Concatenate with spaces.

}
?>

Now we can select and style all pages in the "visible" subsection with a CSS selector such as:

body.subsection-visible #somecontainer {
  background-color: #f0f0f0;
}
  • Eric Weik's blog

Comments

#1 Without Zen?

Visitor's picture

Submitted by Andre M. (not verified) on Wed, 03/24/2010 - 10:05.

Since I developed my own theme, is it possible to do this without the use of zen theme?

  • reply

#2 Zen not required...

Eric Weik's picture

Submitted by Eric Weik on Wed, 03/24/2010 - 11:24.

Hi Andre,

Yes, you can implement this in any theme. Add the
function THEME_preprocess_page(&$vars, $hook) {} code from my example to your template.php (replacing THEME with your theme name). It calls a Zen theme function called zen_id_safe(), so you'll need to implement this in your theme as provided by the Zen theme (it just makes sure that the id output conforms to W3C specifications for ID attributes).

If I were you, I would download the Zen theme and open up zen/zen/template.php, and simply copy and paste the zen_id_safe function declaration into your theme's template.php. While it is open, poke around and see how the Zen theme does things. Even when I am doing theme development "from scratch", I often pull in parts of the Zen theme as recipes. It does a number of useful things.

Or if you want, you can just copy and paste from here:

<?php
/**
* Converts a string to a suitable html ID attribute.
*
* <a href="http://www.w3.org/TR/html4/struct/global.html#h-7.5.2" title="http://www.w3.org/TR/html4/struct/global.html#h-7.5.2">http://www.w3.org/TR/html4/struct/global.html#h-7.5.2</a> specifies what makes a
* valid ID attribute in HTML. This function:
*
* - Ensure an ID starts with an alpha character by optionally adding an 'id'.
* - Replaces any character except alphanumeric characters with dashes.
* - Converts entire string to lowercase.
*
* @param $string
*   The string
* @return
*   The converted string
*/
function zen_id_safe($string) {
 
// Replace with dashes anything that isn't A-Z, numbers, dashes, or underscores.
 
return strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $string));
}
?>

I hope this helps! -Eric

  • reply

#3 The urls

Visitor's picture

Submitted by Andre M. (not verified) on Fri, 03/26/2010 - 14:34.

Hi Eric

Thanks for replying... How unfortunate I cannot test this, since the server I was working on is down at the moment... :( As soon as it becomes online I will try and post here.

Thank you,
Andre M.

  • reply

#4 Some problem

Visitor's picture

Submitted by Andre M. (not verified) on Mon, 03/29/2010 - 11:05.

Hi Eric

I put the mytheme_id_safe function first. Then, below it, I put the mytheme_preprocess_page function. I also added the following code into page.tpl.php:

<?php echo $body_classes; ?>

However, Drupal didn't add any class or id (with subsection-) in body. Also, in admin page, I have the following warning:

warning: implode() [function.implode]: Bad arguments. in /path-to/mytheme/template.php on line 457.

Referring to the following line:

$vars['body_classes'] = implode(' ', $classes);

I must have done something wrong...
Thanks,
Andre

  • reply

Post new comment

Warning
I strongly encourage and welcome links and feedback. However, this site is moderated and comments with inappropriate links are rejected. Please do not post a one-line "Me too" or "Great post!" comment just so you can link to your site. Thank you for your understanding.
The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.
  • Use to create page breaks.

More information about formatting options

Blog Posts (RSS)

About

Hello! My name is Eric Weik. I am a computer scientist, photographer, musician, and occasional blogger. New Rivers Digital is my software consulting business. I am dedicated to using open source software and open data standards for Web development and applications integration. In particular, I am an ardent Drupal fan and specialize in Drupal module development, theming, and data architecture integration.

Contact Details

New Rivers Digital
PO Box 784

Lancaster, VA 22503

Voice+1-804-577-8526
Fax +1-804-462-3229
Contact Form

Content Tags

Abstract B&W Bookmarklet Celestial Clouds CSA Date Drupal Drupal Recipes Drupal Sites Dynamic Range Estuary Government Grasses Long Exposure Macro New Rivers Digital Photoblog Photoset RGB Sketchbook Snow Storm Sumi-e Sunset Surf Theming Trigger.module Views.module Webform.module Zen Zen Theming
more tags

Recent comments

  • 3.x Beta
    7 weeks 6 days ago
  • Some feedback from Webform 3.x
    8 weeks 18 hours ago
  • rainbow art
    8 weeks 20 hours ago
  • Sumi
    10 weeks 2 days ago
  • Thanks for this info! I lost
    11 weeks 1 day ago
  • Look into "Comment Notify"
    18 weeks 2 days ago

Popular content

Today's:

  • Using Drupal Actions, Triggers, and Tokens to Send Notifications About Comments
  • Session Data in Drupal: DO NOT USE sess_read() and sess_write()!
  • Sending Multiple Customized Confirmation Messages with Webform.Module

All time:

  • Using Drupal Actions, Triggers, and Tokens to Send Notifications About Comments
  • Implementing Flickr Slideshow Links By Theming Flickr.module
  • Sending Multiple Customized Confirmation Messages with Webform.Module

Activity Stream

  • Mon, 09/06/2010 - 21:55

  • Flickr Eric posted DSC04355-foxtails 9:55pm #
  • Flickr Eric posted #04361 - Foxtails 9:54pm #
  • Flickr Eric posted DSC04359-foxtails 9:54pm #
  • Thu, 09/02/2010 - 21:05

  • Del.icio.us Eric linked to The Magic Onions 9:05pm#
  • Sat, 08/28/2010 - 23:00

  • Del.icio.us Eric linked to Fanboy.com 11:00pm#
  • Sat, 08/28/2010 - 22:58

  • Del.icio.us Eric linked to Japanese Emoticons: A Stamp of Success ยป Fanboy.com 10:58pm#
  • Del.icio.us Eric linked to http://hypermammut.sourceforge.net/paulstretch/ 10:56pm#
  • Thu, 08/26/2010 - 08:05

  • Del.icio.us Eric linked to Digg - Top in 24 Hours 8:05am#
  • Del.icio.us Eric linked to Kuriositas 11:52pm#
  • Tue, 08/24/2010 - 09:18

  • Del.icio.us Eric linked to Slider | drupal.org 9:18am#
more from my activity-stream


I am a member of the Drupal Association.
Eric At NRD on Drupal.org
Circumjacence (Eric Weik) on Twitter
Circumjacence on Delicious
Eric Weik on Linkedin
Circumjacence (Eric Weik) on Flickr
Circumjacence (Eric Weik) at StumbleUpon

Powered by Drupal & Genesis | Valid XHTML 1.0 Strict | Syndicate content RSS Feed

© 2010 New Rivers Digital | PO Box 784 | Lancaster, Virginia 22503 | +1-804-577-8526 | Contact Form