Inline Twig templates

Inline Twig templates

Inline Twig template

Inline Twig template is a quick and easy way to use Twig syntax in render arrays. I usually use this render element type to add JS scripts to the <body> section of Drupal pages, but you can also use it in controller responses, custom blocks, pseudo fields and so on.

For example let's say that you want to add Google Tag Manager noscript. Documentation says that you have to place the JS snippet immediately after the opening <body> tag on every page of your website. You can use hook_page_top() and inline_template to accomplish this:

function MYMODULE_page_top(&$page) {
  $page['google_tag_noscript_tag'] = [
    '#type' => 'inline_template',
    '#template' => '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>',
  ];
}

You can also provide variables like this:

function MYMODULE_page_top(&$page) {
  $page['google_tag_noscript_tag'] = [
    '#type' => 'inline_template',
    '#template' => '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ container_id }}"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>',
    '#context' => [
      'container_id' => 'GTM-XXXX',
    ],
  ];
}

Please note that you can't use the markup type here because it will strip the style attribute. So, the following doesn't work properly:

function MYMODULE_page_top(&$page) {
  $page['google_tag_noscript_tag'] = [
    '#type' => 'markup',
    '#markup' => '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  ];
}

#markup is passed through \Drupal\Component\Utility\Xss::filterAdmin(), which strips all known XSS attack vectors. You can use #allowed_tags to specify the list of allowed tags, but that won't prevent Drupal from striping attributes. In our case the style attribute will be stripped, so the best bet is to use the inline template.

Recently I had to add a button to a field widget, and I used Inline Twig template like this:

/**
 * {@inheritdoc}
 */
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

...

  $element['remove'] = [
    '#type' => 'inline_template',
    '#template' => '<a href="#" id="remove-button" class="button remove-button">' . $this->t('Remove') . '</a>',
  ];

...

}

It's quite obvious that you can find many usages for this useful render element type.

About author

Goran Nikolovski is a highly experienced Drupal developer with an extensive skill set that includes PHP, MySQL, HTML, CSS and Javascript. He has experience with large Drupal sites and Drupal Commerce 2.x integration, and he is author of several Drupal modules.

You may also like