Hooks are special PHP functions you can create and use to modify or replace behavior of Drupal core and contributed modules/themes in a clean, controlled way.
--> If you are unsure about how Drupal hooks work, please (re-)read the unit on hooks (Reacting to events) first.
Rather than changing Drupal's source code directly, using the hook system for changing Drupal's default behavior:
- Ensures a more stable Drupal installation.
- Ensures your modifications won't be erased the next time you update Drupal core or your contributed modules: changes you introduce via hooks stay in place after updates.
Non-theming related scenarios you can build with hooks include:
- Replacing Drupal's login mechanism with your own mechanism that checks credentials against an external Single Sign-On system.
- Inserting a record in a custom security log table every time a user logs in or out.
- Removing a field from a form provided by another module.
- Showing a status message to the user when a certain event occurs or action is taken.
Template preprocess hooks
Every twig template has a corresponding template preprocess hook that prepares all of the variables that will be available inside that template.
Example: images
The markup for every image is controlled by the image.html.twig template file:
File: /core/modules/system/templates/image.html.twig
{#
/**
* Available variables:
* - attributes: HTML attributes for the img tag.
* - style_name: (optional) The name of the image style applied.
*
* @see template_preprocess_image()
*/
#}
<img{{ attributes }} />The function that provides the variables for this default theme implementation is template_preprocess_image(). It's a bit complicated because it takes many factors into account when deciding which HTML attributes and values to send to the template file.
Don't worry about understanding the exact logic here - we're just demonstrating how a template file and theme hook go together.
function template_preprocess_image(&$variables) {
if (!empty($variables['uri'])) {
$variables['attributes']['src'] = file_url_transform_relative(file_create_url($variables['uri']));
}
// Generate a srcset attribute conforming to the spec at
// http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-srcset
if (!empty($variables['srcset'])) {
$srcset = [];
foreach ($variables['srcset'] as $src) {
// URI is mandatory.
$source = file_url_transform_relative(file_create_url($src['uri']));
if (isset($src['width']) && !empty($src['width'])) {
$source .= ' ' . $src['width'];
}
elseif (isset($src['multiplier']) && !empty($src['multiplier'])) {
$source .= ' ' . $src['multiplier'];
}
$srcset[] = $source;
}
$variables['attributes']['srcset'] = implode(', ', $srcset);
}
foreach ([
'width',
'height',
'alt',
'title',
'sizes',
] as $key) {
if (isset($variables[$key])) {
// If the property has already been defined in the attributes,
// do not override, including NULL.
if (AttributeHelper::attributeExists($key, $variables['attributes'])) {
continue;
}
$variables['attributes'][$key] = $variables[$key];
}
}
}The exact details of what this function does are not relevant at this time.
What's important here is that this function prepares all of the variables that the template needs to add attributes such as src, width, height, title and alt to the ` tag.
If you want to modify these variables before they're sent to the template file, you copy this function into your own theme, change its name in a specific way, and add your own logic.
→ Preprocess hooks let you add variables or modify existing variables before they're sent to the corresponding template.
How to use theme hooks
- Identify which hook you want to implement
- Copy the hook's function signature (name and arguments) into your theme's
.themefile - Provide logic to modify or extend the variables that will be passed into the corresponding template.
- Clear caches.
- Test.
This entire process is similar to identifying the right template file you want to override, copying it into your theme, and adding your custom modifications.
Your hook implementation does not replace the original hook function though. Your hook implementation is called after the original one and possibly implementations by other modules have run.
Modules can implement template preprocess hooks as well?
Yes they can. Imagine a module that adds accessibility-related markup to all of Drupal's components, or take the core RDF module, which adds specific metadata to a lot of Drupal core's markup:
function rdf_preprocess_image(&$variables) {
// Adds the RDF type for image.
$variables['attributes']['typeof'] = ['foaf:Image'];
}Summary
- Each template file has a corresponding template preprocess hook that prepares its variables.
- By implementing a template preprocess hook you can modify variables before they're sent to the template.
- To implement a hook, copy its function signature into your
.themefile and modify its name. - Inside the function body, modify existing variables or add new ones.