Done in 60 seconds: one theme, but different looks for some pages

×

Error message

  • Deprecated function: The each() function is deprecated. This message will be suppressed on further calls in _menu_load_objects() (line 569 of /home/flinkco/public_html/includes/menu.inc).
  • Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /home/flinkco/public_html/includes/common.inc).

When you look closely you'll find that the main pages on http://flink.com.au are "framed" differently from tab to tab. The differences include the background used as well as the note and yellow "sticky" images in the upper right corner. The variations cannot be established via blocks or panels. Yet there's only one active theme.

How did we do this?

The answer lies in the html.tpl.php file, which is new for D7. The master copy lives in modules/system, but depending on the (sub)theme you use an override may live in sites/all/themes/your_theme or even sites/all/themes/your_theme/templates, as is the case with, Sky, the theme used as a base for this site.

html.tpl.php is the new "outer wrapper", enclosing page.tpl.php, which used to be the outermost template in D6, but has been split in D7. It is the html.tpl.php template that generates the tag that starts the main content of each of your pages. In outputting the tag, the template also generates a CSS class attribute which aids enormously in styling your site differently for different contexts, such as front, not-front, logged-in, node-type-article and page-node-34 (where 34 is the node id of the page being viewed).

So now we can change the styling, colours, fonts, borders etc. of any HTML element on the page based on whether the user is logged-in, is viewing an article as opposed to, say, a View etc.

body.front {
   background: orange url(images/background-body1.jpg) repeat-x top;
}
body.not-front {
   background: grey url(images/background-body2.jpg) repeat-x top;
}

The only drawback is that html.tpl.php inserts node id's rather than the aliased path (eg "content-about-us"). To achieve the latter you may want to copy html.tpl.php to your sub-theme and edit the tag line from something like:

   <body class="<?php print $classes; ?>" <?php print $attributes;?> >
to:
   <body class="page-<?php print str_replace('/','-',drupal_get_path_alias()) .' '. $classes; >" <?php print $attributes;?> >

For a quick and dirty just edit modules/system/html.tpl.php, but be aware that in this case your mod will be obliterated when you upgrade to a newer version of Drupal core, so you'll have to reapply the change. It's better to create a subtheme -- it takes less time than you think.

Now you can target elements on specific pages using the alias path, rather than those unfriendly node ids. For instance, the following will put a red border around all images on page content/about-us only:

body.page-content-about-us img {
  border: 1px solid red;
}

Neat!

View more tips and tricks...

File under: 

Drupal 8: contrib roads, take me home

Read More »