Drupal is a powerful content management system that separates data from presentation. Two key concepts that make this possible are render arrays and theme hooks. Understanding these is essential for writing clean, maintainable Drupal code.
1. What is a Render Array?
A render array is a structured PHP array that tells Drupal how to render a piece of content. It is processed recursively by the Renderer service (RendererInterface).
Each element in a render array can contain:
- Properties — keys that start with
#. These tell Drupal how to render the element. Examples include:#markup— simple HTML string#theme— a theme hook to render the element#type— built-in Drupal render element type (container,html_tag, etc.)#attached— add CSS/JS libraries#cache— caching metadata
- Children — keys that do not start with
#. These are nested elements that are rendered recursively. - Theme variables — keys that start with
#and match the variables registered in a theme hook. These are passed to the Twig template.
Example Render Array
$build = [
'#type' => 'container',
'#attributes' => ['class' => ['wrapper']],
'header' => [
'#theme' => 'hello_world_salutation',
'#salutation' => 'Hi',
'#target' => 'Header',
],
'body' => [
'#theme' => 'hello_world_salutation',
'#salutation' => 'Hello',
'#target' => 'Body',
],
'footer' => [
'#markup' => '<p>Goodbye!</p>',
],
];
return $build;
This will produce:
<div class="wrapper">
<h2>Hi, Header (Header)</h2>
<p>Hello, Body!</p>
<p>Goodbye!</p>
</div>
2. What is a Theme Hook?
A theme hook connects render arrays to Twig templates. It defines the variables the template expects and optionally any preprocess functions.
You define a theme hook in your module like this:
function mymodule_theme($existing, $type, $theme, $path) {
return [
'hello_world_salutation' => [
'variables' => [
'salutation' => NULL,
'target' => NULL,
],
],
];
}
Then create a Twig template:
{# hello-world-salutation.html.twig #}
<p>{{ salutation }}, {{ target }}!</p>
When your render array has #theme => 'hello_world_salutation', Drupal uses this template.
3. Theme Hook Suggestions
Sometimes, you need a slightly different template based on context. This is where theme hook suggestions come in.
For example, in a render array:
$build['header'] = [
'#theme' => 'hello_world_salutation',
'#salutation' => 'Hi',
'#target' => 'Header',
'#theme_suggestions' => ['hello_world_salutation__header'],
];
Drupal will first look for hello-world-salutation--header.html.twig. If it doesn’t exist, it falls back to hello-world-salutation.html.twig.
4. Preprocessors and Dynamic Suggestions
You can also add suggestions dynamically in a preprocessor:
function template_preprocess_hello_world_salutation(&$variables) {
if ($variables['target'] === 'Header') {
$variables['theme_hook_suggestions'][] = 'hello_world_salutation__header';
}
}
This approach allows your theme or module to choose a template based on data or conditions.
5. Why Render Arrays and Theme Hooks Matter
- Separation of concerns — data and presentation are clearly separated
- Reusability — templates can be reused across multiple modules and contexts
- Flexibility — suggestions and preprocessors let you customize rendering easily
- Caching — render arrays include cache metadata for performance
Conclusion
Mastering render arrays, theme hooks, and theme hook suggestions is crucial for Drupal developers. They form the backbone of the theming system and allow you to build dynamic, flexible, and maintainable websites.
By combining render arrays with theme hooks and preprocessors, you can control both what data is displayed and how it is presented in a clean, structured way.
Comments