Rendering & Autoescape

Lauri Eskola

Caching in Drupal 8

Different types of caching

 

From fastest to slower:

 

  • Internal page cache
  • Dynamic page cache
  • Render cache

"I'm rendering something. That means I must think of cacheability."

Cacheable metadata

Cache contexts

 

 

"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

 

"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

 

"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.

How to declare cacheable metadata


  $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',
      ],
    ],
  ];

Making something cacheable manually

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' ]

Markup should live inside a Twig template. Not in PHP!

Rule #1

Autoescape

What is escaping?


  <?php

  use Drupal\Component\Utility\Html

  print Html::escape('<em>Kittens</em>');

Prints markup in HTML


 &lt;em&gt;Kittens&lt;/em&gt;

<em>Kittens</em>

Prints in the browser

What is Autoescaping?


  {{ text }}

Prints markup in HTML


 &lt;em&gt;Kittens&lt;/em&gt;

<em>Kittens</em>

  
  <?php

  function bartik_preprocess_page(&$variables) {
    $variables['text'] = '<em>Kittens</em>';
  }

Prints in the browser

Why do we need autoescaping?

Why do we need autoescaping?

How to avoid autoescaping?


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

How to avoid autoescaping?


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

But it has also its caveats...

When autoescaped strings are safe?

Whenever the escaped string is being printed in HTML node.

Attributes are NOT HTML!


  <?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:

New placeholder for URLs

  <?php
  
  use Drupal\Component\Render\FormattableMarkup;

  new FormattableMarkup('<a href=":url"></a>', [
    ':url' => 'javascript:alert(String.fromCharCode(88,83,83))'
  ]);

This is safe:

Array keys

  <?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:

Autoescaping is only enabled  for Twig templates

Which means using any custom templating engine or Theme functions are not autoescaped

That's why PHPTemplate was overtaken by the amazing Nyan Cat templating engine.

https://www.drupal.org/node/2575199

Rendering & Autoescape

By lauriii

Rendering & Autoescape

  • 1,642