Lauri Eskola
From fastest to slower:
"Cache contexts provide a declarative way to create context-dependent variations of something that needs to be cached."
Example
Some expensive-to-calculate data depends on the active theme: different results for different themes. Then you'd vary by the theme cache context.
"Cache tags provide a declarative way to track which cache items depend on some data managed by Drupal."
Example
'node:5' - cache tag for Node entity 5 (invalidated whenever it changes)
"Cache max-age provides a declarative way to create time-dependent caches. "
Example
A cache max -age is a positive integer, expressing a number of seconds.
$build = [
'#prefix' => '',
'#markup' => t('Hi, %name, welcome back to @site!', [
'%name' => $current_user->getUsername(),
'@site' => $config->get('name'),
]),
'#suffix' => '',
'#cache' => [
'contexts' => [
// The "current user" is used above, which depends on the request,
// so we tell Drupal to vary by the 'user' cache context.
'user',
],
],
];
cache keys: when rendering a node (thing) in the teaser view mode (configuration indicating a specific representation), my cache keys would be e.g. [ 'node' , 5 , 'teaser' ]
Rule #1
<?php
use Drupal\Component\Utility\Html
print Html::escape('<em>Kittens</em>');
Prints markup in HTML
<em>Kittens</em>
<em>Kittens</em>
Prints in the browser
{{ text }}
Prints markup in HTML
<em>Kittens</em>
<em>Kittens</em>
<?php
function bartik_preprocess_page(&$variables) {
$variables['text'] = '<em>Kittens</em>';
}
Prints in the browser
{{ text }}
Prints markup in HTML
<em>Kittens</em>
Kittens
<?php
function bartik_preprocess_page(&$variables) {
$variables['text']['#markup'] = '<em>Kittens</em>';
}
Prints in the browser
{{ text }}
Prints markup in HTML
<em>Kittens</em>
Kittens
<?php
use Drupal\Component\Render\FormattableMarkup;
function bartik_preprocess_page(&$variables) {
$variables['text'] = new FormattableMarkup('<em>@txt</em>', ['@txt' => 'Kittens']);
}
Prints in the browser
<?php
use Drupal\Component\Render\FormattableMarkup;
new FormattableMarkup('<em@txt></em>', ['@txt' => 'Kittens']);
new FormattableMarkup('<a href="@url"></a>', ['@url' => 'http://kittens.com']);
new FormattableMarkup('<a href="@url"></a>', [
'@url' => 'javascript:alert(String.fromCharCode(88,83,83))'
]);
These are all dangerous:
<?php
use Drupal\Component\Render\FormattableMarkup;
new FormattableMarkup('<a href=":url"></a>', [
':url' => 'javascript:alert(String.fromCharCode(88,83,83))'
]);
This is safe:
<?php
use Drupal\Core\StringTranslation\TranslatableMarkup;
// These two do the same thing.
$text = new TranslatableMarkup('Translate me');
$text = t('Translate me');
$array[$text] = $text;
<?php
use Drupal\Core\StringTranslation\TranslatableMarkup;
$text = new TranslatableMarkup('Translate me');
$array[(string) $text] = $text;
This will fatal:
This works:
Which means using any custom templating engine or Theme functions are not autoescaped
https://www.drupal.org/node/2575199