Introduction

Sub-themes of core and contributed themes are convenient and efﬁcient in modifying and reusing elements of their base themes, circumstances often require a completely unique approach speciﬁc to our site. Custom themes are the solution for websites which demand a fresh look, using complex layouts, or need so much customization that it would be prudent to start with a clean slate.

Custom themes are the equivalent of handcrafted pieces of art as the themer controls every piece of the puzzle from a design or implementational point of view. This includes setting up the theme using .info ﬁles, choosing the layout, implementing it in a page template, adding regions, styling nodes using node templates, blocks using block templates, and so on. But over time, developers have identiﬁed a list of common tasks, characteristic layouts, and ﬁle and folder hierarchies which are logical, efﬁcient, and promote reuse. This has evolved into what have been dubbed starter themes, themes upon which custom themes are built, usually as sub-themes.

The most popular starter theme for Drupal is Zen. As advertised on its project page, the Zen theme is a ﬂexible standards-compliant and semantically correct XHTML theme that can be highly modiﬁed through CSS and an enhanced version of Drupal's template system. It is designed in modular fashion making it straightforward to change layouts, override templates and theme functions, and to add or remove features. Additionally, the Zen theme comes with extensive documentation within each ﬁle which make things all the more convenient.

With respect to CSS, Zen maintains a number of well documented CSS ﬁles segregated by functionality or location. For example, layout rules are contained within a dedicated layout.css (or similar) ﬁle and page backgrounds are styled within page-backgrounds.css and so on. This makes it convenient when it comes to managing and tracking code changes.

A Zen-based theme contains the following ﬁle and folder structure:

File/folder name

Purpose

template.php

A file where theme overrides and other theme and engine-related code is placed.

theme-settings.php

A file where settings particular to a theme can be placed. These settings are usually exposed on the theme's configuration page.

css/

A folder to store stylesheets.

images/

A folder to store images used in the theme.

images-source/

The folder where the source files for the optimized images in the images folder are available.

Clearing the theme registry

Before we begin, we need to familiarize ourselves with a seemingly trivial yet crucial task that needs to be performed on a routine basis during theme development—clearing the theme registry. The theme registry is essentially a table that Drupal uses to list and track the ﬁles and features of a theme, as well as the theme functions which are being exposed by modules and the theme itself.

While it is recommended practice to turn on Drupal's cache feature only for production sites, the theme registry is built and cached regardless of other caching options. As a result, any changes that affect the structure of the theme will necessitate the clearing of the theme registry.

Getting ready

Rebuilding the registry is an intensive operation which is required only when changes have been made to the theme's ﬁles.

How to do it...

There are a number of ways of clearing the registry. In a stock Drupal installation, visiting admin/settings/performance (Home | Administer | Site conﬁguration | Performance) and clicking on the Clear cached data button will clear all cached data, including the registry, and force a rebuild.

A shortcutIt is sometimes handy to know that the cache and registry can also be cleared by visiting admin/build/themes (Home | Administer | Site building | Themes) and just clicking the Save conﬁguration button.

However, during development or debugging, we will want to clear the registry with great regularity. Rather than having to do so manually, it is often handy to be able to instruct Drupal to perform this operation automatically on every page load. Some themes, including the Zen-based theme which we will be familiarizing ourselves with later in this article, offer an option on their conﬁguration pages to rebuild the registry on every page load. While this is certainly convenient, the recommended method of managing this and other development-oriented operations is through the use of the Devel module.

As the name suggests, the Devel module is one which is tailor-made for use during development. It can be downloaded from http://drupal.org/project/devel. Once the module has been downloaded and installed, navigate to admin/settings/devel (Home | Administer | Site conﬁguration | Devel settings) where the option to Rebuild the theme registry on every page load can be enabled.

How it works...

Drupal maintains a cache of all .info ﬁles, template ﬁles, and theme functions in the theme registry. This registry is a part of the cache table in the Drupal database. When we click on the Clear cache data button in the performance settings page, all Drupal is doing is clearing this entry in the cache table, which automatically forces a rebuild of the registry. The Devel module does the same thing when the Rebuild the theme registry on every page load setting is enabled, except that it does this automatically on every page view.

It is important to keep in mind that rebuilding the registry, or for that matter, clearing any of the caches is an expensive operation which adversely affects the performance of the site. Therefore, it is recommended that this setting only be enabled during development and not in production sites.

Clearing the registry is an important factor to keep in mind during development and especially during debugging.

There's more...

The Devel module also provides a block with handy shortcuts to oft-used areas of the site.

Clearing the cache using the Development block

The Devel module provides a Development block which can be enabled via the block management page at admin/build/blocks (Home | Administer | Site building | Blocks). Once enabled, the block lists, as in the following screenshot, a number of links to perform operations such as emptying the Drupal cache, rebuilding the menu cache, and even reinstalling modules. Emptying the cache will also force a rebuild of the theme registry.

Creating a theme from scratch

While we have previously looked at installing contributed themes and extending base themes using sub-themes, this recipe will outline the steps required to create a custom theme.

Getting ready

It is assumed that the sites/all/themes folder has already been created. This is the recommended location to place custom and contributed themes.

How to do it...

While creating a brand new custom theme, ﬁles such as page.tpl.php will need to be explicitly deﬁned and there is no base theme.

Create a folder with the new theme's name inside the sites/all/themes folder. In this example, we are going to call our theme mytheme.

Visit the theme administration page at admin/build/themes (Home | Administer | Site building | Themes) and we should be able to see a new entry for our theme.

Enable the theme by checking its Enabled checkbox.

Also, set it as the default theme by selecting its Default radio button.

Click the Save conﬁguration button at the bottom of the page to save the changes.

How it works...

Just as with other themes, Drupal scans the sites/all/themes folder looking for .info ﬁles which indicate the presence of a theme. Seeing mytheme.info, it parses the ﬁle and loads the details of the theme, and saves them in the database.

When the new theme is enabled, what we will see is largely unstyled content not unlike the following screenshot. The problem here is that we have not speciﬁed any CSS stylesheets to ay out the page. The only styles being loaded are those that are module-speciﬁc as opposed o theme-speciﬁc.

As we can see, the only stylesheets in evidence are those belonging to core modules and none from our theme. In addition, Drupal has noticed that we do not have any template ﬁles in our theme, most notably, page.tpl.php. Therefore, it has loaded an inbuilt page template ﬁle from modules/system/page.tpl.php and used it instead. Similarly, it is using the node.tpl.php ﬁle from modules/node/ as the basis for each node's layout.

In other words, we have a lot of work ahead of us in getting things up and running especially if our eventual requirements are going to be complicated. As we will see in the next recipe, this is one of the reasons why most themers prefer to use a starter theme and hit the ground running.

Creating myzen, a Zen-based theme

While building a custom theme from scratch is great, most themers prefer to use starter themes as the base for their designs. Starter themes save time and effort as we do not have to perform tedious repetitive tasks and can rely on a tried and tested structure to use as a foundation for our theme.

In this recipe, we will be looking at creating a theme based on the most popular of all starter themes available on drupal.org, Zen.

How to do it...

Paste this folder into sites/all/themes. Rename the folder to the name of our new theme which, in this case, is myzen.

Within this folder, rename the ﬁle STARTERKIT.info.txt to myzen.info.

Open the .info ﬁle in an editor.

Update the name ﬁeld to the name of the theme which in this case is My Zen.

Update the description ﬁeld to My custom zen sub-theme.

Save and exit this ﬁle.

Open template.php in an editor and replace all occurrences of STARTERKIT_ with myzen using the ﬁnd and replace all function.

Save and exit this ﬁle.

Repeat the above ﬁnd and replace operation for the ﬁle theme-settings.php as well.

Save and exit this ﬁle.

Visiting the theme administration page at admin/build/themes (Home | Administer | Site building | Themes) should now display our new theme. Screenshots, favicons, and other niceties can be conﬁgured just like for any other theme.

How it works...

The Zen theme contains a folder named STARTERKIT which is effectively a skeleton theme containing ﬁles and folders which can be readily customized to create a new theme. Once we have made a copy of this folder and renamed its .info ﬁle with the name of our theme, Drupal will recognize our new entry, which is now registered as a sub-theme of Zen as seen in the following screenshot.

While the Zen theme needs to be available, it does not need to be enabled for myzen to function.

Once enabled, the front page of the site will look something like the following screenshot. Here we have a slightly fleshed-out skeleton to work with when we use Zen with a lot of the right pieces already in the right place.

There's more...

The Zen theme comes with a plethora of settings and documentation which can at times, be a little overwhelming. But the rewards of familiarizing ourselves with them are worth our time.

Sub-theme of Zen

We can conﬁrm that this is a sub-theme of Zen via its .info ﬁle which speciﬁes that

base = zen

If we need another theme similar to myzen, we can create one with base = myzen and save ourselves a whole host of repeated operations.

RTFM

Just about every folder which comes with Zen contains a README.txt ﬁle which is ﬁlled to the brim with copious documentation. It is a good idea to always read through these ﬁles. prior to diving in head-ﬁrst.

Rebuild theme registry automatically

The Zen theme contains a setting which rebuilds the theme registry automatically on every page load. This setting is exposed in the .info ﬁle as settings[zen_rebuild_ registry] and also via the theme conﬁguration page.

Choosing a CSS layout for myzen

Layouts decide how elements on a page, customarily contained in DIVs, are positioned. Zen comes with a couple of preset layouts which can be used. If neither of them is suitable, a custom layout can be created. In this recipe, we will be replacing the default ﬁxed-width layout with a liquid layout.

Getting ready

We are going to assume that the myzen theme from earlier in this article is enabled and the current default. It is also important to decide on the type of layout required for the site during the design stage.

How to do it...

All we are going to do here is replace one of the stylesheets used in myzen with another.

Open myzen.info in an editor.

In the section pertaining to stylesheet declarations, look for the line that declares the ﬁxed-width layout which should usually be stylesheets[all][] = css/ layout-fixed.css.

Replace this with stylesheets[all][] = css/layout-liquid.css.

Save the ﬁle.

As usual, clear the theme registry for our changes to take effect.

How it works...

The default ﬁxed-width layout is, as the name suggests, of a ﬁxed width. The positioning of the content does not vary based on the dimensions of the browser. By replacing the layout- fixed.css stylesheet in the myzen.info ﬁle, Drupal will now load the layout-liquid. css ﬁle instead. As a result, when we refresh the front page, we should now see that the ayout of the site occupies the full width of the screen and will flow and reposition itself as we resize the browser window.

There's more...

Zen and its sub-themes take care while displaying content and ensure that the markup is clean and semantically correct. Furthermore, in light of the growing internationalization of the web, it provides RTL support out of the box.

Sidebar support

The Zen theme, by default, comes with two sidebars—left and right—and it automatically displays the sidebar markup only if it contains content within.

RTL

A number of CSS ﬁles in Zen and other themes are often in two variants—one with an rtl sufﬁx and the other without. RTL is an acronym for Right-To-Left and is used to signify that the stylesheet will be used when RTL mode is enabled, customarily for sites with content in languages such as Hebrew and Arabic.

Custom layouts

There are various advantages and disadvantages to using a ﬁxed-width or a liquid layout, and a variety of ways to accomplish these very same layouts which are drastically different from the way Zen implements them. If a custom layout is being used, add the necessary rules and styles to a separate CSS ﬁle such as layout-custom.css.

Overriding Zen template ﬁles with myzen

Zen sub-themes, by default, use the page, node, and other template ﬁles directly from the base theme. In other words, we do not need to specify template ﬁles in our myzen theme unless we have to.

In this recipe, we are going to override the base theme's page.tpl.php template ﬁle with our own copy and make changes to it. As an example, let us see if we can reposition the status messages element which is usually represented by the $messages variable.

Getting ready

We are going to assume that the myzen sub-theme is already created and available.

How to do it...

The following steps outline the procedure to import a template file from the base theme to the sub-theme:

Navigate to the sites/all/themes/zen/templates folder which contains the default templates.

Copy the page.tpl.php file.

Paste it into the sites/all/themes/myzen/templates folder.

Open this file in an editor.

Scroll down looking for any usage of the $messages variable. It should be located in a code block not dissimilar to the following:

What we are looking to do is to move the status messages to a more prominent location above the title and the breadcrumb. After moving the relevant line of code further above, this block should look something like the following:

As we have imported a template file, we also need to clear the theme registry.

We should now be able to see our changes in effect when a node, for example, is updated.

How it works...

Once we copied the template file from Zen to myzen and subsequently cleared the registry, Drupal was alerted during the theme registry rebuilding process that a new page.tpl.php file was available. Due to the fact that this template file was located in the myzen theme's folder, it took precedence over the version contained within the Zen theme's folder leading to our updates taking effect.

It is interesting to note that while the page.tpl.php template file in myzen took precedence over the file in the Zen folder, the latter was already overriding the equivalent template file in Drupal's system module folder.

The following screenshots should offer a before and after comparison of this recipe in action:

In the preceding screenshot, we can see that the status message is being displayed below the title of the node. However, with our new template file in action, we can see that the status message is now displayed above the title and the breadcrumb as shown in the following screenshot:

Adding a custom region to myzen

Regions are essentially containers for Drupal blocks. The layout of regions in a page effectively dictates the layout of the site.

The myzen theme contains the following regions by default:

First sidebar

Second sidebar

Navigation bar

Highlighted content

Content top

Content bottom

Header

Footer

Page closure

In this recipe, we will be looking to replace the existing Content bottom region with two separate regions named Content bottom 1 and Content bottom 2 respectively.

Getting ready

We are going to assume that the myzen theme from earlier in this article is enabled and the current default. We will be updating the default page.tpl.php template file that is used by myzen. If this file does not exist in sites/all/themes/myzen/templates, it will need to be imported into this folder from sites/all/themes/zen/templates/page.tpl.php.

Save the file and exit. Now that we have added our new regions, we need to ensure that Drupal uses them by updating the page.tpl.php template.

Open myzen's page.tpl.php file in an editor.

Scroll down and look for the following line of code:

<?php print $content_bottom; ?>

Replace the line in step 2 with the following two:

<?php print $content_bottom1; ?><?php print $content_bottom2; ?>

Save the file and exit.

Clear the theme registry as per usual.

The new regions should now be visible if we navigate to the blocks administration page at admin/build/blocks (Home Administer | Site building | Blocks|).

How it works...

The following two screenshots should offer a before-and-after comparison of the blocks administration page. Each region in the layout is depicted by a yellow bar containing the name of the region.

In the original layout, as displayed in the previous screenshot, we can see the regions highlighted in yellow. These regions include the lone Content bottom, situated below the content of the page. By simply editing the .info file, we have been able to replace this single option with two new regions, Content bottom 1 and Content bottom 2, as seen in the following screenshot.

Adding a background image to the theme

Zen-based themes come with a plethora of stylesheets separated logically by functionality. In this recipe, we will be exploring their use by adding a background image to our myzen theme.

Getting ready

As usual, we are going to assume that myzen is enabled and is the current default theme. Since we are going to be using a background image in this recipe, it will also be a good idea to ensure that the myzen theme is using a fixed-width layout to improve the visibility of the background.

The background image to be used should be optimized and saved in the sites/all/ themes/myzen/images/ folder. In this recipe, we will be setting the image file named body-bg.png as the background and repeating it along both the X and Y axes.

How to do it...

As Zen-based themes use stylesheets partitioned based on their functionality, we can add our rules to the file page-backgrounds.css as follows:

Navigate to the sites/all/themes/myzen/css folder which contains a set of stylesheets available for customization.

Look for the file named page-backgrounds.css and open it in an editor.

The first rule which we are concerned with is the one for the body tag. Locate it and add the following highlighted rule to set the background image:

body { background: url(../images/body-bg.png) repeat;}

Since the CSS file is within the css folder, we need to use the ../images/ body-bg.png syntax to reference the file within the images folder.

The next element we are going to be styling is the DIV with id="#page" which contains the regions of the layout. Look for the entry for #page and add the following rule to it:

#page { background: #EEE;}

Save the file and exit.

How it works...

The page-backgrounds.css file is added to the theme via its .info file. The myzen.info file will, by default, have a whole host of CSS files included not unlike the following list:

Commented code In the preceding excerpt from the .info file, lines prefixed with a semicolon are deemed to have been commented out and are not considered.

Most of the CSS files referenced in the file are skeleton stylesheets, each with its own functionality and purpose. They are usually littered with a lot of documentation and examples to get us started. In this case, the page-backgrounds.css file is already included and our rules should take effect automatically. It is important that we limit our changes in this stylesheet to rules pertaining to page element backgrounds. Including extraneous styles will defeat the purpose of partitioning the CSS based on functionality.

The resulting front page should now have a tiled background image for its body and a gray background for its content as demonstrated in the following screenshot:

There's more...

Stylesheet management can sometimes be an involved process and is largely dependent on our own personal preferences.

Custom file structures

Some themers are uncomfortable with managing the multitude of CSS files that come with Zen and other themes. They either prefer their own logical structures or use a single monolithic stylesheet containing all the rules. There is nothing really wrong with this and it is simply a question of comfort and ease of use.

Unused stylesheets

Once we are done styling our theme, we will usually find that there are a number of stylesheets included in myzen.info which are empty or never used. Rather than deleting the relevant lines, it is prudent to just comment them out by prefixing them with a semicolon.

Adding a conditional stylesheet in Zen

Conditional stylesheets are a frequent requirement to accommodate hacks and workarounds specific to versions of the Internet Explorer browser. While other themes would require us to conditionally introduce said stylesheets either using a module or by inserting the appropriate HTML directly in the page.tpl.php template, Zen-based themes offer a straightforward alternative.

In this recipe, we will be looking at the procedure involved in adding a conditional stylesheet which is loaded only if the browser is Internet Explorer (IE). Furthermore, the version of the browser has to be 7 (IE7) or greater.

Getting ready

This recipe centers around the myzen sub-theme which is assumed to have been created, enabled and set as the default theme. A CSS file named ie7.css should be created and saved inside myzen's css folder. Hacks and workarounds particular to IE7 are to be added to this file.

How to do it...

Adding a conditional stylesheet to the myzen theme can be accomplished as follows:

Navigate to the sites/all/themes/myzen folder.

Open the myzen.info file in an editor.

Scroll down to the section dealing with conditional stylesheets. The default configuration should look something like the following:

As evident from the preceding source, Zen translates our entries in the .info file to conditional comments and inserts them as markup. The conditional comments are only triggered in Internet Explorer which includes the appropriate stylesheet accordingly.

There's more...

The maintainers of the Zen theme have made this functionality available to other themes as well through the use of a dedicated module.

Conditional stylesheets for other themes

The conditional stylesheets module (http://drupal.org/project/conditional_ styles) provides similar functionality for non-Zen themes. A number of themes rely on this module to simplify the process of adding conditional comments.

Modifying myzen's theme settings

Visiting the theme configuration page for the myzen theme created earlier in this article should reveal a number of theme-specific settings. In this recipe, we are going to learn how these settings are added and then, rather than creating our own setting, we will familiarize ourselves with their structure by learning how to remove an existing setting.

Getting ready

As we are working with the myzen theme, it should be enabled and set as the site's default theme. Furthermore, as detailed in the recipe where myzen was created, all instances of STARTERKIT in the theme-settings.php file should be replaced by myzen. Once this is done, the theme configuration page for the myzen theme should include theme-specific settings as in the following screenshot.

How to do it...

The setting that we will be removing is the Show block editing on hover checkbox. To do so, we will be working with three different files—myzen's theme-settings.php, myzen.info, and Zen's theme-settings.php.

Load all three files in three separate editors.

Comparing myzen's theme-settings.php and Zen's theme-settings.php, we can tell that all the settings in the preceding screenshot are exported by Zen via a function named zen_settings(). myzen gets access to these settings as it is a sub-theme of Zen. The block editing links setting appears in the following block of code:

Navigate back to myzen's theme configuration page at admin/build/themes/ settings/myzen (Home Administer | Site building | Themes | Configure|) and refresh the page to confirm that the Show block editing on hover checkbox is no longer present.

Click on the Save configuration button at the bottom of the page to ensure that any vestiges of the setting are also cleared from the database.

We still have a little more work to do. Even though the checkbox appears to have vanished, hovering over a nearby block will result in a block edit link appearing.

The culprit is the following block of code in myzen_settings:

// Get the default values from the .info file.$defaults = zen_theme_get_default_settings('myzen');// Merge the saved variables and their default values.$settings = array_merge($defaults, $saved_settings);

What is happening is that default settings from the myzen.info file are being loaded as well. Looking at the file in an editor the following telltale entry appears to be the one responsible:

settings[zen_block_editing] = 1

Commenting out this line of code and subsequently, clearing the theme registry should sort our problem out.

How it works...

The Zen theme exports a set of variables and allows its sub-theme, myzen, to act upon them by updating their values, adding new settings, or removing existing ones. The addition of new settings can be achieved through the use of the Forms API while removal of existing settings is performed using an unset() operation. Furthermore, default values for each settings can be added or removed via myzen.info as well.

Alerts & Offers

Series & Level

We understand your time is important. Uniquely amongst the major publishers, we seek to develop and publish the broadest range of learning and information products on each technology. Every Packt product delivers a specific learning pathway, broadly defined by the Series type. This structured approach enables you to select the pathway which best suits your knowledge level, learning style and task objectives.

Learning

As a new user, these step-by-step tutorial guides will give you all the practical skills necessary to become competent and efficient.

Beginner's Guide

Friendly, informal tutorials that provide a practical introduction using examples, activities, and challenges.

Essentials

Fast paced, concentrated introductions showing the quickest way to put the tool to work in the real world.

Cookbook

A collection of practical self-contained recipes that all users of the technology will find useful for building more powerful and reliable systems.

Blueprints

Guides you through the most common types of project you'll encounter, giving you end-to-end guidance on how to build your specific solution quickly and reliably.

Mastering

Take your skills to the next level with advanced tutorials that will give you confidence to master the tool's most powerful features.

Starting

Accessible to readers adopting the topic, these titles get you into the tool or technology so that you can become an effective user.

Progressing

Building on core skills you already have, these titles share solutions and expertise so you become a highly productive power user.