9

Started to dive into Drupal 8 twig, and what better place to start than from the top: html.html.twig

But found this:

<head-placeholder token="{{ placeholder_token|raw }}">

Here is the change record:

And some related issues:

And the documentation:

But nothing really clarifies why this was done.

Is this a Drupalism? A Twigism? What are these tokens for?

The only other time I've seen a placeholder token system like this was with CTools where they create a placeholder in the generated HTML output and then go back later and replace the token with the actual value. If this is the same concept, why does Drupal core need to do this? (The CTools system was ostensibly to get around some core limitations).

4

2 Answers 2

8

The reason why placeholder_token is used in html.html.twig instead of using just a normal variable is that in Drupal 8 we have different render strategies than just the simple rendering where everything gets rendered in the template and we are able to collect the assets.

In the Drupal cores default Renderer we have placeholders (placeholders might attach some additional assets). If we would print the assets in a normal variable it would happen before all the assets have been collected. So what Drupal 8 does is it first renders everything with the normal rendering in the template, then it replaces the placeholders and collects assets from then, and after all that has been done we finally replace the asset placeholders to add the assets to the page.

2
  • This is pretty insightful. Thanks. Lauriii do you know if there is a new workflow diagram of the HTML building and rendering process for Drupal 8? Dec 7, 2015 at 16:08
  • 2
    There is actually diagram and more info available here: drupal.org/developing/api/8/render/pipeline
    – lauriii
    Dec 7, 2015 at 22:24
6

TL;DR: In a practical scenario <head-placeholder token="{{ placeholder_token|raw }}"> == {{ head }}

The issue where this change was introduced is: Move attachment processing to services and per-type response subclasses

And like this change record says this:

 <head-placeholder token="{{ placeholder_token|raw }}">

Just replace this:

{{ head }}

The token attribute is just for avoid collisions it doesn't have any other special purpose.

You can see at Theme.inc at the function template_preprocess_html the following code:

$types = [
  'styles' => 'css',
  'scripts' => 'js',
  'scripts_bottom' => 'js-bottom',
  'head' => 'head',
];
$variables['placeholder_token'] = Crypt::randomBytesBase64(55);
foreach ($types as $type => $placeholder_name) {
  $placeholder = '<' . $placeholder_name . '-placeholder token="' . 
  $variables['placeholder_token'] . '">';
  $variables['#attached']['html_response_attachment_placeholders'][$type] = $placeholder;
}

Which basically builds all the tokens and put them in the html_response_attachment_placeholders array.

Later when the page is being rendered the tokens are replaced by the data (scripts,styles etc) see HtmlResponseAttachmentsProcessor::processAttachments

3
  • "The token attribute is just for avoid collisions it doesn't have any other special purpose." To avoid collisions with what, exactly? Nov 21, 2015 at 2:09
  • 1
    With any other placeholder_name that could be added in the future or in a different theme, this was discussed here and added to the code here and FabianX mention to all the place holders are now unique here
    – Gnuget
    Nov 21, 2015 at 2:15
  • 1
    If you need to change what is output here, that's configuration or code. You can of course add things that you'd normally add in your <head> section directly in your theme's html.html.twig file, if they don't need to obey any caching rules. So for instance you could disable the Favicon element in your theme settings and then paste in an expanded set of favicon-related links and meta tags here.
    – mlncn
    Mar 1, 2019 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.