You are here

class TwigEnvironment in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Template/TwigEnvironment.php \Drupal\Core\Template\TwigEnvironment

A class that defines a Twig environment for Drupal.

Instances of this class are used to store the configuration and extensions, and are used to load templates from the file system or other locations.

Hierarchy

  • class \Drupal\Core\Template\TwigEnvironment extends \Drupal\Core\Template\Twig_Environment

Expanded class hierarchy of TwigEnvironment

See also

core\vendor\twig\twig\lib\Twig\Environment.php

2 files declare their use of TwigEnvironment
HelpTopicTwig.php in core/modules/help_topics/src/HelpTopicTwig.php
TwigExtensionTest.php in core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
1 string reference to 'TwigEnvironment'
core.services.yml in core/core.services.yml
core/core.services.yml
1 service uses TwigEnvironment
twig in core/core.services.yml
Drupal\Core\Template\TwigEnvironment

File

core/lib/Drupal/Core/Template/TwigEnvironment.php, line 18

Namespace

Drupal\Core\Template
View source
class TwigEnvironment extends \Twig_Environment {

  /**
   * Key name of the Twig cache prefix metadata key-value pair in State.
   */
  const CACHE_PREFIX_METADATA_KEY = 'twig_extension_hash_prefix';

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * Static cache of template classes.
   *
   * @var array
   */
  protected $templateClasses;

  /**
   * The template cache filename prefix.
   *
   * @var string
   */
  protected $twigCachePrefix = '';

  /**
   * Constructs a TwigEnvironment object and stores cache and storage
   * internally.
   *
   * @param string $root
   *   The app root.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   The cache bin.
   * @param string $twig_extension_hash
   *   The Twig extension hash.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   * @param \Twig_LoaderInterface $loader
   *   The Twig loader or loader chain.
   * @param array $options
   *   The options for the Twig environment.
   */
  public function __construct($root, CacheBackendInterface $cache, $twig_extension_hash, StateInterface $state, \Twig_LoaderInterface $loader = NULL, array $options = []) {
    $this->state = $state;

    // Ensure that twig.engine is loaded, given that it is needed to render a
    // template because functions like TwigExtension::escapeFilter() are called.
    // @todo remove in Drupal 9.0.0 https://www.drupal.org/node/3011393.
    require_once $root . '/core/themes/engines/twig/twig.engine';
    $this->templateClasses = [];
    $options += [
      // @todo Ensure garbage collection of expired files.
      'cache' => TRUE,
      'debug' => FALSE,
      'auto_reload' => NULL,
    ];

    // Ensure autoescaping is always on.
    $options['autoescape'] = 'html';
    if ($options['cache'] === TRUE) {
      $current = $state
        ->get(static::CACHE_PREFIX_METADATA_KEY, [
        'twig_extension_hash' => '',
      ]);
      if ($current['twig_extension_hash'] !== $twig_extension_hash || empty($current['twig_cache_prefix'])) {
        $current = [
          'twig_extension_hash' => $twig_extension_hash,
          // Generate a new prefix which invalidates any existing cached files.
          'twig_cache_prefix' => uniqid(),
        ];
        $state
          ->set(static::CACHE_PREFIX_METADATA_KEY, $current);
      }
      $this->twigCachePrefix = $current['twig_cache_prefix'];
      $options['cache'] = new TwigPhpStorageCache($cache, $this->twigCachePrefix);
    }
    $this
      ->setLoader($loader);
    parent::__construct($this
      ->getLoader(), $options);
    $policy = new TwigSandboxPolicy();
    $sandbox = new \Twig_Extension_Sandbox($policy, TRUE);
    $this
      ->addExtension($sandbox);
  }

  /**
   * Invalidates all compiled Twig templates.
   *
   * @see \drupal_flush_all_caches
   */
  public function invalidate() {
    PhpStorageFactory::get('twig')
      ->deleteAll();
    $this->templateClasses = [];
    $this->state
      ->delete(static::CACHE_PREFIX_METADATA_KEY);
  }

  /**
   * Get the cache prefixed used by \Drupal\Core\Template\TwigPhpStorageCache
   *
   * @return string
   *   The file cache prefix, or empty string if the cache is disabled.
   */
  public function getTwigCachePrefix() {
    return $this->twigCachePrefix;
  }

  /**
   * Gets the template class associated with the given string.
   *
   * @param string $name
   *   The name for which to calculate the template class name.
   * @param int $index
   *   The index if it is an embedded template.
   *
   * @return string
   *   The template class name.
   */
  public function getTemplateClass($name, $index = NULL) {

    // We override this method to add caching because it gets called multiple
    // times when the same template is used more than once. For example, a page
    // rendering 50 nodes without any node template overrides will use the same
    // node.html.twig for the output of each node and the same compiled class.
    $cache_index = $name . (NULL === $index ? '' : '_' . $index);
    if (!isset($this->templateClasses[$cache_index])) {
      $this->templateClasses[$cache_index] = parent::getTemplateClass($name, $index);
    }
    return $this->templateClasses[$cache_index];
  }

  /**
   * Renders a twig string directly.
   *
   * Warning: You should use the render element 'inline_template' together with
   * the #template attribute instead of this method directly.
   * On top of that you have to ensure that the template string is not dynamic
   * but just an ordinary static php string, because there may be installations
   * using read-only PHPStorage that want to generate all possible twig
   * templates as part of a build step. So it is important that an automated
   * script can find the templates and extract them. This is only possible if
   * the template is a regular string.
   *
   * @param string $template_string
   *   The template string to render with placeholders.
   * @param array $context
   *   An array of parameters to pass to the template.
   *
   * @return \Drupal\Component\Render\MarkupInterface|string
   *   The rendered inline template as a Markup object.
   *
   * @see \Drupal\Core\Template\Loader\StringLoader::exists()
   */
  public function renderInline($template_string, array $context = []) {

    // Prefix all inline templates with a special comment.
    $template_string = '{# inline_template_start #}' . $template_string;
    return Markup::create($this
      ->createTemplate($template_string)
      ->render($context));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
TwigEnvironment::$state protected property The state service.
TwigEnvironment::$templateClasses protected property Static cache of template classes.
TwigEnvironment::$twigCachePrefix protected property The template cache filename prefix.
TwigEnvironment::CACHE_PREFIX_METADATA_KEY constant Key name of the Twig cache prefix metadata key-value pair in State.
TwigEnvironment::getTemplateClass public function Gets the template class associated with the given string.
TwigEnvironment::getTwigCachePrefix public function Get the cache prefixed used by \Drupal\Core\Template\TwigPhpStorageCache
TwigEnvironment::invalidate public function Invalidates all compiled Twig templates.
TwigEnvironment::renderInline public function Renders a twig string directly.
TwigEnvironment::__construct public function Constructs a TwigEnvironment object and stores cache and storage internally.