Drupal 7 Theming
Changes in Drupal7 and Theme Inheritance
Summary
Assumes some knowledge of Drupal themesAssumes some knowledge of HTML/CSS
@aimee_mareewww.aimeemaree.com
Drupal Solution Architect @demonzmediaFreelance Open Source Solution Design
Believer in Free Speech and Free Libre Open Source Software
This presentation was created using Libre Office
What is a Theme
In a CMS a presentation layer displays the content to website visitors based
on a set of templates
“A theme is a collection of files that define the presentation layer.” –
Drupal.org
Think of it as the index.html with static content replaced by PHP variables
Biggest theme change since Drupal 4.7
That’s nice but, what does it all mean anyway?
New functions for content$content does not require preprocess functions in order to split content
Two new functions for printing out node variables render() and hide()
<div class="content"> <?php // First we hide the comments and links now so that we can render them later. hide($content['comments']); hide($content['links']); // Then we print the content. Comments and links not included here. print render($content); ?></div> // Then we print the links and comments separately<?php print render($content['links']); ?><?php print render($content['comments']); ?>.
Bye Bye PHPTemplate overridesFunction names must match theme name
In Drupal6 you could override theme functions with calling PHPTemplate.engine
function phptemplate_breadcrumb()
In Drupal7 this has been depreciated
function THEMENAME_breadcrumb()
box.tpl.php is now extinct
Template delimiter changeTemplate suggestions in Drupal7 must be separated by -- not -
node--news.tpl.php
You can still use - to separate names
node--media-article.tpl.php
node--content-type-machine-name.tpl.php
Default regions in Drupal7Drupal7 has new default regions
headerhelp (new region to display help)
highlight (replaces mission)
content (must be included in a theme)
sidebar_firstsidebar_secondfooter
Hidden regions in Drupal7Drupal 7 now has hidden regionsModules can print content out to hidden regions without needed to create a block
The below example would print content but not wishlist, however a module can print its output to the region wishlist
regions[content] = Contentregions[wishlist] = Wishlistregions_hidden[] = wishlist
Hiding CSS elements
Two new CSS classes to assist with hiding CSS elements in Drupal7
.element-hidden hides an element from all users
.element-invisible hides an element visually, which means it remains available to screen readers
More CSS changes
Drupal 7 is adhering to CSS naming conventions
.clear-block was removed and replaced with .clearfix
In Drupal6 we would call <div class="clear-block">
Now in Drupal7 we call <div class="clearfix">
More power to be an individual
Preprocess and Process
Process functions will run after preprocess functions
This enables a two step approach when variables need to be worked on in two phases;
In preprocess you can add classes into an Array
In process you can flatten the array into a string for template printing
Preprocess functions
In Drupal7 they apply to both templates and functions
Preprocess functions are called before process functions
The preprocessor enables variables to be placed within .tpl.php files
Theme Hook Alter
Hook Alter is no longer just for modules
hook_page_alter – allows all variables displayed on a page to be altered/hiddenhook_form_alter – allows small tweaks to forms, no need to create a custom modulehook_js_alterhook_css_alter
No longer need node.tpl.phpIn Drupal6 we needed to have node.tpl.php in our theme in order to theme content types
sites/all/themes/ourtheme/node.tpl.php sites/all/themes/ourtheme/node-event.tpl.php
In Drupal7 we no longer need node.tpl.php in our theme in order to theme content types
modules/node/node.tpl.php sites/all/themes/ourtheme/node--event.tpl.php
Did somebody mention wildcards?
Wildcard Suggestions
Drupal7 can now use wildcard suggestions in template names
Drupal6, needed to know the specific IDPage-user.tpl.php would theme all user pages as well as the log-in, to theme only the user pages you would need to specify the integer for all Page-user-42.tpl.php, Page-user-32.tpl.php
Drupal7, you can specify a wildcard So you can theme all user pages but not the login page--user--%.tpl.php
Over 50 theme changes in Drupal7$content now appears in block admin UI
Blocks have more meaningful CSS classes .block-blog-recent
$classes variable can be added to your preprocess hooks
Additions to drupal_add_css()
Classes and Attributes are now standard and predefined
All titles now have $prefix and $suffix added
Drupal7 Accessibility Changes
Accessibility Changes
RDFa can now be included, make sure you add;
<head profile=”<?php print $grddl_profile; ?>
Adding “Skip to Navigation” to core themes
Removal of duplicate and null tags
Creation of the D7AX hash tag for accessibility for module and theme maintainers
Some modules/themes now include WAI-ARIA
So many Templates?
html.tpl.php
Webpage output is now constructed by html.tpl.php and not page.tpl.php
Page.tpl.php has been split aparthtml.tpl.php now contains the content between <head> </head> and constructs the template
html.tpl.php calls page.tplAllows for more granular control
html.tpl.php
page.tpl.php
No longer contains the header information that's in html.tpl.php
No longer constructs the template thats html.tpl.php job
Is now called from html.tpl.php
Now only contains the contents between the wrapper DIV ie the header, sidebars, page content
page.tpl.php
node.tpl.php
As with Drupal6 in Drupal7 node prints out the main content area
No longer need to have node.tpl.php in your theme when creating custom node.tpl's
Can theme specific node's
node--nodeid.tpl.phpnode--type.tpl.phpnode.tpl.php
node.tpl.php
region.tpl.php
New to Drupal 7 allows ease of changing region styling
Can theme all regions or themes a specific region
Allows you to wrap more HTML and CSS code around the region area
region.tpl.php
Allows more control of Drupal out-put
region.tpl.php will allow you to style all regions the same
To style the menu differently you can specify region--menu.tpl.php
Can theme all regions region.tpl.php
Can theme a specific regionregion—search.tpl.php
region.tpl.php
field.tpl.php
New to Drupal 7
Fields can be themed with field.tpl.phpCan theme individual fields or groups of field types
Will theme all the fields that are of that type
Must flush cache when adding and removing templates
field.tpl.php
For example you create an image field and use that across three content types, the field theme will apply the field.tpl.php to all three content types
field.tpl.phpfield--field-type.tpl.phpfield--field-name.tpl.phpfield--content-type.tpl.phpfield--field-name--content-type.tpl.php
field.tpl.php
Putting it all together
But Drupal likes to add its own HTML?
The Inheritance Process
Drupal inheritance works as a system of overrides
Has a specific cascading order (some exceptions noted)
Powerful, because it enables you to override the things you don't like
All changes live within your theme, leaving the system defaults alone
So we OVERRIDE and don't HACK
Drupal Overrides
ModulesCore
Theme Engine
Theme C Override
A Default
B Override
Theme Registry can also be manipulated
Template Inheritance
1.Drupal core applies its own .tpl.php files they are called first
2.Drupal modules apply their own .tpl.php files these are applied second and over write any css calls that exist in core tpl.php files
3.Your theme has its own .tpl.php files these are applied last and over write calls in core tpl.php files and module tpl.php files
4. Your theme has the final say!
Drupal .tpl.php inheritance
core tpl.php files
/modules/node/node.tpl.php
module tpl.php files
/sites/all/modules/examplemodule/node.tpl.php
theme tpl.php files
/sites/all/themes/ourtheme/templates/node.tpl.php
Core node.tpl.php gets overridden by the modules node.tpl.php
module node.tpl.php gets overridden by the them node.tpl.php
Theme Wins
Nothing to inherit?
core tpl.php files
/modules/node/html.tpl.php
File does not exist
/sites/all/modules/examplemodule/?
File does not exist
/sites/all/themes/ourtheme/templates/?
Core html.tpl.php is applied to the layout
There is no file to overwrite the core so it is used to create the output
Core Wins
There is no file to overwrite the core tpl file
Inheritance within your own themeTemplates within your own Theme can also be overwritten by other templates in your theme this allows you to be specific with your template target
Drupal.org describes it as “Template suggestions are made based on these factors
Listed from the most specific template to the least.
Drupal will use the most specific template it finds.”
In Drupal most specific wins
node.tpl.php
node--type.tpl.php
node--nodeid.tpl.php
node.tpl.php will be called to theme all Drupal nodes
node—nodeid.tpl.php will apply to the specific node that matches the id number
Specific Wins
node--type.tpl.php will apply to all nodes of a specific content type
Drupal module theming
There are 42 different .tpl files in Drupal7 core modules folder.
/modules/modulename/*.tpl.php
Each one of these can be copied and placed in your own theme to overwrite the output
/sites/all/theme/yourtheme/templates/*.tpl.php
If a contributed module has a .tpl file this can be copied into your theme folder and it will overwrite the .tpl in the modules folder
/sites/all/modules/example/*.tpl.php
So to theme a module?
1.Take a copy of the .tpl.php file we need from the module
1.Move the copy to our themes templates folder, this can be under the folder theme/templates/*.tpl.php or under the root of the theme folder theme/*.tpl.php
1.Flush cache or flush the theme registry to see if we can notice the changes on the website
But what about functions?
Theme functions are also Inherited
1.Modules provide their own theme functions
2.Find the theme function in .module3.Copy the function into your template.php file
4.Change the function name from theme_pager to your-theme_pager
5.Flush cache6.Your theme has the final say!
Theme Function Inheritance
Core module file themes the pager, this is considered the default
theme_pager()
Your template.php in sites/all/themes/your_theme
theme_pager()
Drupal looks in your theme folder first
If it finds the function there it applies it and stops looking
If no function is found in your theme then the default is applied
Theme Wins
Setting Template Variables
1.Locate the preprocess function you want to change the variable for
2.Copy the preprocess function into your template.php file
3.Change the function name to match your theme name
4.Your template.php has the final say!
Preprocess Inheritance
Core module file themes the pager, this is considered the default
function garland_preprocess(&$vars, $hook) { if … }
Your template.php in sites/all/themes/your_theme
function yourtheme_preprocess(&$vars) {$vars['new_variable'] = 'happy hippie'; }
Preprocess calls $vars and also $hook allows your template.php to hook in and change the variable
Variable is appended to your new value
Your theme Wins
What about sub-themes?
Pre-process functions are stackedDo not get overwritten but stack on top of each other
What does this mean?
If we declare in our sub theme the same preprocess functions as our base theme it will get added to the base theme and not overwrite it
Template.php is stacked
The sub-theme and base theme template.php file will be stacked
base theme is included first and then our sub-theme is included
This means we inherit from our base theme and append to our sub theme for template.php
Sub-themes inherit from base
Template files can be overwritten by adding that .tpl.php inside our subtheme
Theme function overwrites work in the same way we can recreate a base thee function in our template.php and this will overwrite the base theme settings
We can overwrite CSS / JavaScript files by incuding them in our subtheme .info file
What is not inherited in sub-themes?Theme settings are not inherited
So if we want our sub theme to have these we need to;
1. copy the theme-settings.php from the base theme folder
2. place into our sub-theme folder
3. make any modification's we need to our sub-theme file
So many CSS files
Drupal core CSS
1.Drupal core applies its own .css file this is called first
2.Drupal modules apply their own .css files these are applied second and over write any css calls that exist in core css files
3.Your theme has its own .css files these are applied last and over write calls in core css files and module css files
4.Your theme has the final say!
Drupal CSS inheritance
Core css files style a header tag
h1 { font-size: 1.6em; }
If module .css file has the same class call, it will be overwritten by the module css
h1 { font-size: 2em; }
If theme .css file has the same class call, it will be overwritten by the theme css
h1 { font-size: 3em; }
Core css calls get overridden by the modules if there is a file with the same name style.css
Module css calls gets overridden by the theme css calls
Theme Wins
Inheritance Don't and Do’sDo save your theme folder/files into /sites/all/themes [correct]Don't edit or save files in /themes [not correct]
Don't over write core themes files that live in the base folder of Drupal, this is called hacking coreDont take a copy of a core theme to create another theme Do use a contributed theme or create sub theme from a base theme
You see a CSS class coming from module/node/node.css? Don’t change the module/node/node.css file Do copy the css call and paste it into your theme.css file
You want to use your own css to style a module? Don’t change sites/all/modules/name/module.css file Do take a copy of the css file, place a copy of the module.css file
into your theme folder and enter stylesheets[all][] = modulestyle.css into your themes info file Do flush cache
Oh did I mention Clear Cache?
Recommended Themes
Boron re-writes Drupal core templates into HTML5 with WAI-ARIA roles and WCAG 2.0 compliance
Mothership removes core CSS and HTML markup to provide a cleaner base
Stark shows the core CSS and HTML mark-up provided by Drupal
Omega and Adaptive WCAG 1.0 compliance some WAI-ARIA support allow for responsive theming
Its a lot to take in
@aimee_mareeAimee Maree Forsstromwww.aimeemaree.comDrupal Solution Architect