Sub-theme structure and inheritance

Sub-themes are just like any other theme, with one difference: They inherit the parent theme's resources. There are no limits on the chaining capabilities connecting sub-themes to their parents. A sub-theme can be a child of another sub-theme, and it can be branched and organized however you see fit. This is what gives sub-themes great potential.

sub-themes and dependancies

Imagine starting with a base theme designed as wireframes, then applying and refining all the details from a sub-theme. Then, from the same wireframe, testing out alternate designs by branching out another sub-theme. Working on a multi-site installation but you need a cohesive look and feel? With sub-theming, a lot of the design resources can be shared. Site-specific changes can be set to a specific sub-theme, but any shared resources can be edited once to be applied across all the installations. With careful planning, the possibilities are endless.

Creating a sub-theme

The sub-theme to-be should be located in its own directory. Prior to Drupal 6, this directory had to be a subdirectory of its base theme; in Drupal 6 and 7 it can be placed outside of the base theme's directory.

To declare your theme to be a sub-theme of another, it is necessary to alter the sub-theme's .info file. Add the following line to the sub-theme's .info to declare its parent or "base theme." Change "themeName" to the internal name of the parent theme (that is, the name of the parent theme's .info file).

base theme = themeName

Style sheet inheritance

All style sheets defined in the parent theme will be inherited, as long as you declare at least one stylesheet in your sub-theme's .info file. You must declare at least one stylesheet in your sub-theme for any of the parent theme's stylesheets to be inherited.

Overriding inherited style sheets: Specify a style sheet with the same filename in the sub-theme. For instance, to override style.css inherited from a parent theme, add the following line to your sub-theme's .info file:

stylesheets[all][]   = style.css

You will also need to create the style.css stylesheet file; if you simply wish to disable the imported styles, you can create an empty file.

JavaScript inheritance

All JavaScripts defined in the parent theme will be inherited.

Overriding inherited JavaScript: Specify a JavaScript file with the same filename in the sub-theme's .info file. For instance, to override script.js inherited from a parent theme, add the following line to your sub-theme's .info file:

scripts[] = script.js

You will also need to create the script.js stylesheet file; if you simply wish to disable the imported styles, you can create an empty file.

Template.php function inheritance

Anything defined in the parent theme's template.php file will be inherited. This includes theme function overrides, preprocess functions and anything else in that file. Each sub-theme should also have its own template.php file, where you can add additional functions or override functions from the parent theme.

Overriding inherited template.php functions: In your sub-theme's template.php file, you can redeclare functions from the parent theme's template.php (using your sub-theme's name as the function prefix) to override specific functions. There is no way to prevent all functions in the parent theme from being inherited.

Page, node, block and other template (.tpl.php) file inheritance

Drupal 7 Any .tpl.php files from the parent theme will be inherited. You can add template files with more specificity -- for instance, node-blog.tpl.php building on an inherited node.tpl.php.

Drupal 6: Any .tpl.php files from the parent theme will be inherited. However, to add template files with more specificity, you must also copy over the more general template file from the parent theme manually. For instance, to add a node-blog.tpl.php template in a sub-theme, you must also copy over node.tpl.php from the parent theme. This bug has been fixed in Drupal 7 but will not be fixed in Drupal 6.

Overriding inherited .tpl.php templates: Add a template file with the same name in your sub-theme folder to have it override the template from the parent theme.

Screen shots and logo inheritance

The parent theme's screen shot will be inherited. The parent theme's logo (logo.png/logo.jpg) will not be inherited.

Overriding inherited screen shots: Specify a new image file in your sub-theme's .info file.

Region inheritance

Sub-themes do not inherit custom regions from a parent theme. If you are using custom regions, you should copy the region declarations from the parent theme's .info file. Be sure your sub-theme's page.tpl.php file matches the sub-theme's region settings.

Color and theme settings inheritance

Color.module support within the color directory is not inherited.

Theme settings set via advanced theme settings' theme-settings.php are not inherited.

How do you create a sub theme?

daveslc - May 7, 2010 - 06:02

The section "Creating a sub-theme" says nothing about how to actually create a sub theme. It only says how to modify your theme to be a sub theme of another.

What are the steps needed to actually create a sub-theme?

It's easier than you think!

mparker17 - May 12, 2010 - 13:49

Suppose I have a theme named parent_thm, and I want to make a subtheme named child_thm.

I would start creating my subtheme the same way I would start making any new theme: by adding a new folder to the appropriate themes directory; giving this folder the same name as the theme I want to create.

For example, suppose I am adding my themes to a site in single-site configuration; and I extracted the Drupal tarball to the path /var/www/. I would then create a new folder inside /var/www/sites/default/themes/ with the name child_thm (i.e.: this new folder would be /var/www/sites/default/themes/child_thm/).

As an aside: I can choose any parent theme I want — it doesn't matter whether the parent theme I choose was built in to the Drupal core, downloaded from the contributed themes directory or was created by me. Also, the parent theme doesn't have to be in /var/www/sites/default/themes/: it could also be in /var/www/sites/themes/, /var/www/sites/all/themes/ or /var/www/sites/mysite.example.com/themes/.

The second step in creating a new theme is to add a .info file in the new folder, also named after my theme. So, in my example, I would create: /var/www/sites/default/themes/child_thm/child_thm.info.

I would then edit child_thm.info, as usual; except that I would add the following line somewhere:

base theme = parent_thm

Drupal will automatically include parent_thm's CSS and JavaScript before child_thm's; and, when outputting the HTML, it would fall back to using any .tpl.php files in parent_thm if they were missing in child_thm.

For a good (albeit complex) example, see The Zen theme's STARTERKIT.info.

Theme and module with the same name = no content

Wumms - May 25, 2010 - 16:11

Thanks for the nice summary. One thing to add: when naming your sub-theme, avoid using the same name for a theme and a module. If you do you will just have "Array" as content of your blocks (I suppose the module and theme functions interfere with each other). I renamed the theme and everything's fine now.

Or worse :)

grobot - July 10, 2010 - 01:04

Themes may implement theme_block(). Modules may implement hook_block(). Having a module and a theme which occupy the same namespace will cause either function to be picked up for both roles.

If your module's hook_block() is picked up by the theme layer, you will see array() as the contents of all blocks.

I'm not sure what happens if your theme's theme_block() matches a module name. Probably nothing disastrous? Let us know!

If both exist, you'll get a fatal error when the theme attempts to redefine the function already defined by the module.

This is touched on in Doesn't Play Nicely. hook_block() is gone in D7 for this (and other) reasons.

If my comments have helped you, please pay it forward!
Use issue queues to discuss module issues - this will help your questions assist others (including yourself!) in future.
http://twitter.com/grobot ● www.giantrobot.co.nz

Overriding inherited style sheets

vegantriathlete - May 30, 2010 - 03:22

This guide says that to prevent inheritance you will need to create the style sheet and that it can be empty. However, the documentation in the the zen/STARTERKIT.info.txt says that we don't need to have a file with that name; all we need to do is the array declaration:

stylesheets[all][]   = style.css

if we wanted to prevent inheritance of style.css.

Can someone clarify stylesheet inheritance?

benlotter - July 14, 2010 - 03:07

This document says:
You must declare at least one stylesheet in your sub-theme for any of the parent theme's stylesheets to be inherited
This does not seem accurate to me as it does not match what I experienced in creating a subtheme. Here are the steps to reproduce inherited stylesheets without declaring any stylesheets in subtheme.info.

  1. Create a parent theme with the following stylesheets.
    • default.css
    • layout.css
    • style.css
    • print.css
  2. Add other stylesheet in template.php using drupal_add_css(), let's call it dropdown_menus.css.
  3. Create a subtheme.info only declaring the parent theme.
  4. The subtheme will inherit all of the above except style.css and print.css which I understand to be the 2 stylesheets that Drupal will automatically add to your theme if none are declared.

Can someone please clarify this documentation or my undestanding of it?

Benjamin Lotter
"Delight thyself also in the LORD and He shall give thee the desires of thine heart." ~Psalm 37:4

Sub-theme bug

juan_g - August 23, 2010 - 23:24

There is an important D6 sub-theme (and sub-sub-theme) bug, #481142: Theme settings forms are not inherited by sub-themes, with a patch by Zen's maintainer JohnAlbin (#26) that seems to work but has been waiting for review for a long time.

 
 

Drupal is a registered trademark of Dries Buytaert.