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.

Creating a Custom Twig Template

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:

|- src
|  |- Controller
|  |  |- ThemeExampleController.php
|  |- Element
|  |  |- MyElement.php
|- templates
|  |- my-element.html.twig
|- theme_example.module

Implementing hook_theme

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;

Creating the Controller

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.'),

Creating the Render Element

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)

Defining the Twig Template

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 }}

{{ }}

We print the element

{{ element }}


{{ }}


{{ element.description }}

#pre_render addition

{{ element.pre_render_addition }}

Random number (not printed when we printed the whole element)

{{ element['#random_number'] }}

Understanding the Flow

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.


Saved you some valuable time?

Buy me a drink 🍺 to keep me motivated to create free content like this!