To simplify the life of Drupal themers, Drupal has a template system. It can be extended using the hook_theme().
A theming hook defined in the hook_theme
function can later be overridden in a theme through a theme function or template file. Here’s how to define it in a module named example_template
:
function example_template_theme() {
return array(
'custom_template' => array( // name of the theming hook
'variables' => array( // variables available in the template
'body' => NULL,
'title' => NULL,
),
),
);
}
Now, to use this theming hook, you should call it like this:
theme('custom_template', array('body' => 'Some body', 'title' => 'Some title'));
The first parameter is the name of the theming hook, and the second parameter is an array of variables defined for this hook.
In your module, define either a default theme function or a template that will be used. To do this, create a function named theme_THEMING_HOOK_NAME()
:
Defining the function in your module:
function theme_custom_template($variables) {
$output = '<div class="custom-template-wrapper">';
$output .= '<div class="body">';
$output .= $variables['body'];
$output .= '</div>';
$output .= '<div class="title">';
$output .= $variables['title'];
$output .= '</div>';
$output .= '</div>';
return $output;
}
To use a template file from your module as the default, you need to specify the template location in hook_theme()
:
function example_template_theme() {
return array(
'custom_template' => array(
'variables' => array( // variables available in the template
'body' => NULL,
'title' => NULL,
),
// template name, in this case custom_template.tpl.php in module root
'template' => 'custom_template',
),
);
}
After defining this theming hook, you can override it in any theme:
function MYTHEME_custom_template($variables) {
$output = '<div class="mytheme-custom-template-wrapper">';
$output .= $variables['title'] . ' - ' . $variables['body'];
$output .= '</div>';
return $output;
}
To use a template instead of a function, create a template file named example_template.tpl.php
and place it in the theme folder or inside the theme’s templates
subfolder.
IMPORTANT! You cannot use both a theme function and a template simultaneously. The theme function has higher priority and will always be used if defined.
Complete code:
/**
* @file
* Example template
*/
/**
* Implements hook_menu().
*/
function example_template_menu() {
$items['example_template'] = array(
'title' => 'Example template',
'page callback' => 'example_template_callback',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implements hook_theme().
*/
function example_template_theme() {
return array(
'custom_template' => array( // name of the theming hook
'variables' => array( // variables available in the template
'body' => NULL,
'title' => NULL,
),
// template name, custom_template.tpl.php in module root
'template' => 'custom_template',
),
);
}
/**
* Page callback.
*/
function example_template_callback() {
return theme('custom_template', array('body' => 'Some body', 'title' => 'Some title'));
}
/**
* Returns HTML for a custom template.
*
* @param $variables
* An associative array containing:
* - body: body text.
* - title: title text.
*
* @ingroup themeable
*/
function theme_custom_template($variables) {
$output = '<div class="custom-template-wrapper">';
$output .= '<div class="body">';
$output .= $variables['body'];
$output .= '</div>';
$output .= '<div class="title">';
$output .= $variables['title'];
$output .= '</div>';
$output .= '</div>';
return $output;
}