|Read more about this book|
(For more resources on Drupal, see here.)
With the arrival of Drupal 6, sub-theming really came to the forefront of theme design. While previously many people copied themes and then re-worked them to achieve their goals, that process became less attractive as sub-themes came into favor. This article focuses on sub-theming and how it should be used to customize an existing theme.
We'll start by looking at how to set up a workspace for Drupal theming.
Setting up the workspace
Before you get too far into attempting to modify your theme files, you should put some thought into your tools. There are several software applications that can make your work modifying themes more efficient. Though no specific tools are required to work with Drupal themes, you could do it all with just a text editor—there are a couple of applications that you might want to consider adding to your tool kit.
The first item to consider is browser selection. Firefox has a variety of extensions that make working with themes easier. The Web Developer extension, for example, is hugely helpful when dealing with CSS and related issues. We recommend the combination of Firefox and the Web developer extension to anyone working with Drupal themes. Another extension popular with many developers is Firebug, which is very similar to the Web developer extension, and is indeed more powerful in several regards.
Pick up Web developer, Firebug, and other popular Firefox add-ons at https://addons.mozilla.org/en-US/firefox/.
There are also certain utilities you can add into your Drupal installation that will assist with theming the site. Two modules you definitely will want to install are Devel and Theme developer. Theme developer can save you untold hours of digging around trying to find the right function or template. When the module is active all you need to do is click on an element and the Theme developer pop-up window will show you what is generating the element, along with other useful information like potential template suggestions. The Devel module performs a number of functions and is a prerequisite for running Theme developer.
Note that neither Devel nor Theme Developer are suitable for use in a development environment—you don't want these installed and enabled on a client's public site, as they can present a security risk.
When it comes to working with PHP files and the various theme files, you will also need a good code editor. There's a whole world of options out there, and the right choice for you is really a personal decision. Suffice it to say: as long as you are comfortable with it, it's probably the right choice.
Setting up a local development server
Another key component of your workspace is the ability to preview your work—preferably locally. As a practical matter, previewing Drupal themes requires the use of a server; themes are difficult to preview with any accuracy without a server to execute the PHP code. While you can work on a remote server on your webhost, often this is undesirable due to latency or simple lack of availability. A quick solution to this problem is to set up a local server using something like the XAMPP package (or the MAMP package for Mac OSX).
XAMPP provides a one step installer containing everything you need to set up a server environment on your local machine (Apache, MySQL, PHP, phpMyAdmin, and more). Visit http://www.ApacheFriends.org to download XAMPP and you can have your own Dev Server set up on your local machine in no time at all.
Follow these steps to acquire the XAMPP installation package and get it set up on your local machine:
- Connect to the Internet and direct your browser to http://www.apachefriends.org.
- Select XAMPP from the main menu.
- Click the link labeled XAMPP for Windows.
- Click the .zip option under the heading XAMPP for Windows.
- Note that you will be re-directed to the SourceForge site for the actual download.
- When the pop-up prompts you to save the file, click OK and the installer will download to your computer.
- Locate the downloaded archive (.zip) package on your local machine, and double-click it.
- Double-click the new file to start the installer.
- Follow the steps in the installer and then click Finish to close the installer.
That's all there is to it. You now have all the elements you need for your own local development server.
To begin, simply open the XAMPP application and you will see buttons that allow you to start the servers.
To create a new website, simply copy the files into a directory placed inside the /htdocs directory. You can then access your new site by opening the URL in your browser, as follows: http://localhost/sitedirectoryname.
As a final note, you may also want to have access to a graphics program to handle editing any image files that might be part of your theme. Again, there is a world of options out there and the right choice is up to you.
Planning the modifications
A proper dissertation on site planning and usability is beyond the scope of this article. Similarly, this article is neither an HTML nor a CSS tutorial; accordingly, in this article we are going to focus on identifying the issues and delineating the process involved in the customization of an existing theme, rather than focusing on design techniques or coding-specific changes.
Any time you set off down the path of transforming an existing theme into something new, you need to spend some time planning. The principle here is the same as in many other areas. A little time spent planning at the frontend of a project can pay off big in savings later.
When it comes to planning your theming efforts, the very first question you have to answer is whether you are going to customize an existing theme or whether you will create a new theme. In either event, it is recommended that you work with sub-themes. The key difference is the nature of the base theme you select, that is, the theme you are going to choose as your starting point.
In sub-theming, the base theme is the starting point. Sub-themes inherit the parent theme's resources; hence, the base theme you select will shape your theme building. Some base themes are extremely simple, designed to impose on the themer the fewest restrictions; others are designed to give you the widest range of resources to assist your efforts. However, since you can use any theme for a base theme, the reality is that most themes fall in between, at least in terms of their suitability for use as a base theme.
Another way to think of the relationship between a base theme and a subtheme is in terms of a parent-child relationship. The child (sub-theme) inherits its characteristics from its parent (the base theme). There are no limits to the ability to chain together multiple parent-child relationships; a sub-theme can be the child of another sub-theme.
When it comes to customizing an existing theme, the reality is often that the selection of the base theme will be dictated by the theme's default appearance and feature set; in other words, you are likely to select the theme that is already the closest to what you want. That said, don't limit yourself to a shallow surface examination of the theme. In order to make the best decision, you need to look carefully at the underlying theme's file and structures and see if it truly is the best choice. While the original theme may be fairly close to what you want, it may also have limitations that require work to overcome. Sometimes it is actually faster to start with a more generic theme that you already know and can work with easily. Learning someone else's code is always a bit of a chore and themes are like any other code—some are great, some are poor, most are simply okay. A best practices theme makes your life easier.
In simplest terms, the process of customizing an existing theme can be broken into three steps:
- Select your base theme.
- Create a sub-theme from your base theme.
- Make the changes to your new sub-theme.
Why it is not recommended to simply modify the theme directly? There are two following reasons:
- First, best practices say not to touch the original files; leave them intact so you can upgrade them without losing customizations.
- Second, as a matter of theming philosophy, it's better to leave the things you don't need to change in the base theme and focus your sub-theme on only the things you want to change. This approach to theming is more manageable and makes for much easier testing as you go.
Selecting a base theme
For the sake of simplicity, in this article we are going to work with the default Bartik theme. We'll take Bartik, create a new sub-theme and then modify the subtheme to create the customized theme. Let's call the new theme "JeanB".
Note that while we've named the theme "JeanB", when it comes to naming the theme's directory, we will use "jeanb" as the system only supports lowercase letters and underscores.
In order to make the example easier to follow and to avoid the need to install a variety of third-party extensions, the modifications we will make in this article will be done using only the default components. Arguably, when you are building a site like this for deployment in the real world (rather than simply for skills development) you might wish to consider implementing one or more specialized third-party extensions to handle certain tasks.
|Read more about this book|
(For more resources on Drupal, see here.)
Creating a new sub-theme
The steps involved in creating a new sub-theme are detailed as follows, but in a nutshell, it works like this:
- Make a copy of the theme directory (and its contents).
- Rename the directory.
- Delete the files you don't need.
- Update the theme name inside the files you want to keep.
- Create a new stylesheet.
- Update the .info file.
So, let's get started.
Create a copy of the base theme
Access your Drupal installation on your server, and then make a copy of the Bartik theme directory (located at /themes/bartik).
Create the sub-theme in a new directory
Paste the copy of the directory containing the Bartik files into the /sites/all/themes directory and rename it to reflect our new theme's name: jeanb. So you should now have a new directory at: sites/all/themes/jeanb.
Delete the files you don't need
Our sub-theme will inherit mostly everything from the base theme. The exception being the .info file (and a new stylesheet that we will create later). Given that inheritance is the norm, you should eliminate everything from the sub-theme that you don't plan to change. In other words, if there's no change planned for the file, delete it from the sub-theme's directory.
For purposes of this example, let's assume that we want to add a custom template for the front page and that we need the template.php file for some themable function overrides. Given those requirements, let's keep those two files, plus our .info file, and let's get rid of everything else. The next step, therefore, is to open up our new directory and delete everything except .info, /templates/page.tpl.php, and template.php. Also keep the /css directory, but delete all the contents; we will use that directory to hold our sub-theme's new CSS files.
Note that there's no reason to keep all that stuff inside the template.php file; go ahead and clean out the file. If you decide at a later stage to override any of the file contents, you can always copy it from the original file and add it to our new template.php. Go ahead and clean out your template.php file now—leave only the <?php at the top (that's important!).
Update the theme name throughout the sub-theme
We need to change every occurrence of "bartik" in our sub-theme to "jeanb". If you've got a code editor, you can run a find/replace to get this done, if not, you'll need to crack open each file and do this.
Create a stylesheet for your sub-theme
Next, let's create a new .css file. This is a requirement for a valid sub-theme; you need at least one stylesheet. Create an empty file, name it jeanb.css, and put it in the /css directory.
Update the sub-theme's .info file
The final step in the process is to update your .info file. First, rename it jeanb.info (if you have not already done so when you changed all the occurrences of "bartik" to "jeanb".) Next, open up the file and perform the following operations on the contents:
- Make sure the name has been updated.
- Update the description line as you see fit - this information will appear inside the Theme Manager as a description for the theme.
- Delete the lines for package, version, and core.
- Add a new line: base theme = bartik.
- Declare our new stylesheet by adding this line: stylesheets[all] = css/jeanb.css.
- Delete all other stylesheet declarations.
- Save the file.
At the end of this process, your jeanb.info file should look like this:
; $Id: bartik.info,v 1.5 2010/11/07 00:27:20 dries Exp $
name = JeanB
description = A new sub-theme based on Bartik.
base theme = bartik
engine = phptemplate
stylesheets[all] = css/jeanb.css
regions[header] = Header
regions[help] = Help
regions[page_top] = Page top
regions[page_bottom] = Page bottom
regions[highlighted] = Highlighted
regions[featured] = Featured
regions[content] = Content
regions[sidebar_first] = Sidebar first
regions[sidebar_second] = Sidebar second
regions[triptych_first] = Triptych first
regions[triptych_middle] = Triptych middle
regions[triptych_last] = Triptych last
regions[footer_firstcolumn] = Footer first column
regions[footer_secondcolumn] = Footer second column
regions[footer_thirdcolumn] = Footer third column
regions[footer_fourthcolumn] = Footer fourth column
regions[footer] = Footer
settings[shortcut_module_link] = 0
; Information added by drupal.org packaging script on 2011-01-05
version = "7.0"
project = "drupal"
datestamp = "1294208756"
Note that sub-themes do not inherit custom regions from the parent theme. Therefore if you want to use the custom regions in the original Bartik, you will need to re-specify them, as you can see in the preceding .info file.
Additionally, your/sites/all/themes directory should look like the following:
If all has gone according to plan, the new JeanB can now been seen inside the Disabled Themes section of your site's Theme Manager, as shown in the following figure:
At this point, go ahead and make the theme visible on the site so that you can see the impact of my work. To do this, select the option to Enable and set default from the links that you see immediately below JeanB in the previous screenshot.
If you view the frontend of the site, you will see that there is a very little difference between the presentation of your new JeanB and the original Bartik. One thing you will notice is that the logo file is missing—the base theme's logo file is not inherited by the sub-themes, so you will need to add your own logo.
Now, at last, you are ready to begin implementing your customizations.
Note that the Bartik theme uses the Color module functionality. In my preceding example, I have not included porting the Color module into this sub-theme. The Color module functionality is not inheritable. If you wanted to use that feature in your sub-theme, you would need to include in the sub-theme the /color directory together with all its contents and the /css/colors.css file. You would also need to declare the colors.css file in the jeanb.info file.
|Read more about this book|
(For more resources on Drupal, see here.)
Customizing the sub-theme
The first question you need to ask yourself is: Do I need to customize the styling, or do I need to customize the structure? (Of course there is always the chance that the answer to both is 'yes.') We pose this question as it frames the next steps: If you only need to customize the styling, then you just need to look at working with the theme's CSS. Assuming that adequate selectors are already in place in the code, this means simply overriding some of the system's many styles. If, on the other hand, you need to customize the structure, then you are likely needed to override templates or themable functions.
Note that the Drupal theme system caches template files, theme functions, and .info files. Accordingly, as you work on the theme and make changes to any of those elements, you should refresh Drupal's cache in order to see your change take effect immediately.
The process of customizing a theme into something new consists of a set of tasks that can be categorized into three groups:
- Configuring the theme.
- Adapting the CSS.
- Adapting the templates and themable functions, if needed.
Let's look first at how you can make the most out of configuring your new sub-theme.
Configuring the theme
You can work with the configuration options in Drupal's theme Manager, so, we are not going to go through all those options here. Moreover, if you can achieve the customization that you need through simple configuration, there would be no need to set up a sub-theme; instead, you would simply install the theme you need and then configure it. Configuration changes are not at risk during upgrades and patches.
Still, in terms of work process, it is worth noting that you should do your configuration before you get started working on your styling and other customizations. If you don't set everything up now—and that includes installing all required modules and positioning your blocks—then you sometimes later find that changes made in one area impact another in an unexpected fashion. It's better to set up everything that you can at the beginning and then, as you work, the impact of your styling and overrides become more obvious and easier to deal with.
Don't forget to check user permissions as you enable new modules!
Auto-generate your dummy content
Temporary dummy content allows you to see text on the screen as you make your changes, and helps you to judge more easily your fonts, colors, spacing, and margins. The Devel module, referenced earlier in this article, allows you to automatically populate your site with sample data, including comments, taxonomies—even menus and users! This brilliant little utility can spare you the tedium of creating pages of lorem text, comments, and so on. To use this feature, you must first install the Devel module and then enable the option Devel generate (this option is visible in the Module Manager). Now, when you need sample content, visit the Configuration Manager and look for the heading Generate items. Select what you want from the list. Simple, fast, painless—another reason you will love the Devel module.
Adapting the CSS
If you are happy with the structure of your base theme and you only need to tailor the styling, it is conceivable that you will need to do no more than configure your theme and customize the CSS. Given the wealth of CSS selectors built into the system, you can do quite a bit using only the CSS—particularly if you select a pure CSS base theme and you are handy with CSS.
We've set up JeanB as a sub-theme of the Bartik theme. As a result, the JeanB theme has available to it not only the stylesheets in the parent theme (Bartik) but also any additional stylesheets existing in the JeanB directory, for example, the file we created earlier, jeanb.css.
- Override a single selector: To override or add to an existing selector, simply place another version of the selector in the jeanb.css file. Don't forget that properties in the original selector will be inherited if there are no conflicting properties in the jeanb.css file.
- Adding new selectors: To create a new selector, simply put it into the jeanb.css file.
- Override an entire stylesheet: To override an entire stylesheet, place a stylesheet of the same name in the JeanB/css directory and then add it into the JeanB.info file. This approach can be used regardless of whether you are trying to override the base theme's CSS or one of the core CSS files located elsewhere in the system. In either event, as long as the stylesheet names are the same, Drupal will give precedence to the style sheet defined in the active theme's directory.
Precedence and Inheritance
Where one style definition is in an imported stylesheet and another in the immediate style sheet, the rule in the immediate style sheet (the one that is importing the other style sheet) takes precedence.
Where repetitive definitions are in the same stylesheet, the one furthest from the top of the stylesheet takes precedence in the case of conflicts; where repetitive definitions are in the same stylesheet, non-conflicting attributes will be inherited.
Modifying a default template
If you wish to modify the structure of your base theme, or if you need to provide specific page templates for specific pages or groups of pages, then you will need to look into going further and tapping into the power of the Drupal theming hooks—the templates and the themable functions. In this section of the article, I look at various issues relating to overriding templates from within a sub-theme; in the next section I look at working with the themable functions.
The Bartik theme includes a number of templates that are intended to override their counterparts in the Drupal core. Inside Bartik's /templates directory you will find:
All of the templates previously listed are inherited by JeanB. Inside your sub-theme you have the same choices you would have if you were creating a new base theme: You can override the templates in the base theme, or you can create completely new overrides that take precedence over templates located elsewhere in the core, or you can create new overrides using template suggestions.
- Overriding a template in the base theme: To modify any of these templates, simply make a copy of the template and paste it into JeanB's/templates directory—that's all it takes.
- Override a core template: To override a system template, you use exactly the same approach, that is, make a copy of the original template and paste it into JeanB's/templates directory.
- Create a template suggestion: You will note that I left the page.tpl.php template inside JeanB when I created the sub-theme. This is because I want to create a custom home page template for JeanB. We use a specific template suggestion that tells the system to use this template for the home page. To make this work, simply duplicate page.tpl.php and change the name to page--front.tpl.php. Make your changes to the new template and you now have a customized template that is served when a visitor views the home page.
If you wish to use a template suggestion, the suggestion and the base template must be placed in the same directory.
Overriding a themable function
You can create themable functions overrides that are specific to your sub-theme by using the template.php file located inside the sub-theme's directory.
Function overrides and preprocess functions located in the base theme are inherited by your sub-themes. If you don't need to add function overrides or preprocess functions to your sub-theme, there is no need to have a template.php file inside your sub-theme directory.
- Overriding a base theme function override: If you wish to modify one of the function overrides already created inside the base theme, you will need to copy the code from the base theme's template.php file, paste it into the sub-theme's template.php, and modify the function's name to be consistent with the sub-theme. For example, in the Bartik theme's template.php file, we will find an override to the function theme_menu_tree().
return '<ul class="menu clearfix">' . $variables['tree'] . '</
- To customize this for JeanB, you will need to copy the function, paste it into JeanB's template.php file, and then rename it from bartik_menu_tree to jeanb_menu_tree. The new code will appear like this:
return '<ul class="menu clearfix">' . $variables['tree'] . '</
Remember to clear the Drupal cache each time you change a themable function or template.
- Overriding a core themable function: Simply copy the original function, place it in the sub-theme's template.php file, and modify the function name to reflect the sub-theme's name.
- Converting a themable function into a dedicated template: Create a new template file inside your sub-theme. Name the file in line with the name of the function, converting any underscores to hyphens. (Using the example seen previously, if you wanted to convert the function theme_menu_tree() into a template, then the template would be name menu-tree.tpl.php.) Next copy the output portion of the original function and paste it into the template file.
Preprocess functions can also be added into your sub-theme, via the template.php file. As with the themable functions, the name of the preprocess function must be modified to reflect the name of the sub-theme.
This article began with a discussion of the tools you will need to begin working on your themes in earnest. The Devel module and the Theme Developer module are two of the key tools you will want to have at your disposal.
We learned to manage the customization of an existing theme. In this article we dealt with one of the most powerful techniques available to themers—the use of sub-themes.
This article showed how to create a sub-theme and then how to implement various common approaches to customizing that sub-theme.
- Drupal 7 Themes: Creating Dynamic CSS Styling [Article]
- Drupal 7 Themes: Dynamic Theming [Article]
- 25 Useful Extensions for Drupal 7 Themers [Article]
- Drupal and Ubercart 2.x: Install a Ready-made Drupal Theme [Article]
- Building an Admin Interface in Drupal 7 Module Development [Article]
- Content in Drupal: Frequently Asked Questions (FAQ) [Article]
- Drupal Web Services: Twitter and Drupal [Article]