Custom twig templates provide a flexible way to create unique markup for your Drupal 10 website. In this blog post, we will walk you through the process of using a custom twig template with a render element in Drupal 10. This will help you understand the workflow and how to customize the process for your own projects.
Before diving into the code, let's set up the basic structure of our custom twig template. Start by creating a new module called 'theme_example'. Inside the module, create the following files and folders:
theme_example
|- src
| |- Controller
| | |- ThemeExampleController.php
| |- Element
| | |- MyElement.php
|- templates
| |- my-element.html.twig
|- theme_example.module
In the 'theme_example.module' file, we will implement the hook_theme function to define our custom render element. This function will return an array containing the render element name and a 'render element' key pointing to the string 'element':
/**
* Implements hook_theme().
*/
function theme_example_theme() {
$items = [
'my_element' => [
'render element' => 'element',
],
];
return $items;
}
Next, we will create a controller file at 'src/Controller/ThemeExampleController.php' that extends ControllerBase. This controller will return a render array containing two examples:
namespace Drupal\theme_example\Controller;
use Drupal\Core\Controller\ControllerBase;
class ThemeExampleController extends ControllerBase {
public function simple() {
return [
'example one' => [
'#markup' => '<div>Markup Example</div>',
],
'example two' => [
'#type' => 'my_element',
'#label' => $this->t('Example Label'),
'#description' => $this->t('This is the description text.'),
],
];
}
}
Now, we'll create the 'src/Element/MyElement.php' file, which will define the custom render element by extending the RenderElement class:
namespace Drupal\theme_example\Element;
use Drupal\Core\Render\Element\RenderElement;
use Drupal\Core\Url;
class MyElement extends RenderElement {
public function getInfo() {
$class = get_class($this);
return [
'#theme' => 'my_element',
'#label' => 'Default Label',
'#description' => 'Default Description',
'#pre_render' => [
[$class, 'preRenderMyElement'],
],
];
}
public static function preRenderMyElement($element) {
// ... (Add the code for pre-rendering the element)
}
}
Create a twig template called 'my-element.html.twig' in the 'templates' folder. Use the provided variables to create your custom markup:
<div class="myElement">
<div class="randomNumber">Random Number: {{ element['#random_number'] }}</div>
{{ element.description }}
{{ element.link }}
We print the element
{{ element }}
Link
{{ element.link }}
Description
{{ element.description }}
#pre_render addition
{{ element.pre_render_addition }}
Random number (not printed when we printed the whole element)
{{ element['#random_number'] }}
The custom twig template is linked to the render element through the '#theme' key in the 'getInfo()' method of the custom render element class. In our example, the key is 'my_element', which corresponds to the 'my-element.html.twig' template file.
In the controller, we use the '#type' key to indicate the render element we want to use. In this case, we set it to 'my_element', which is the same key used in the 'hook_theme()' function. This links our custom render element to the twig template, allowing us to render it with our custom markup.
When rendering the custom twig template, the '#pre_render' method is called to prepare the render array for the template. This is where we can create and modify the variables that will be used in the twig template, such as links, descriptions, and random numbers.