Commit 08b92945 authored by catch's avatar catch

Issue #2317557 by dawehner, Cottser, joelpittet, jhodgdon: Fixed renderInline...

Issue #2317557 by dawehner, Cottser, joelpittet, jhodgdon: Fixed renderInline not compatible with twig_auto_reload.
parent 57fc2615
......@@ -30,13 +30,6 @@ class TwigEnvironment extends \Twig_Environment {
*/
protected $templateClasses;
/**
* The string loader implementation used for inline template rendering.
*
* @var \Twig_Loader_String
*/
protected $stringLoader;
/**
* Constructs a TwigEnvironment object and stores cache and storage
* internally.
......@@ -66,7 +59,6 @@ public function __construct(\Twig_LoaderInterface $loader = NULL, ModuleHandlerI
}
$this->templateClasses = array();
$this->stringLoader = new \Twig_Loader_String();
$options += array(
// @todo Ensure garbage collection of expired files.
......@@ -77,7 +69,8 @@ public function __construct(\Twig_LoaderInterface $loader = NULL, ModuleHandlerI
// Ensure autoescaping is always on.
$options['autoescape'] = TRUE;
parent::__construct($loader, $options);
$this->loader = new \Twig_Loader_Chain([$loader, new \Twig_Loader_String()]);
parent::__construct($this->loader, $options);
}
/**
......@@ -92,12 +85,9 @@ protected function isFresh($cache_filename, $name) {
/**
* Compile the source and write the compiled template to disk.
*
* @param bool $inline
* TRUE, if the $cache_filename is a rendered template.
*/
public function updateCompiledTemplate($cache_filename, $name, $inline = FALSE) {
$source = $this->getLoader($inline)->getSource($name);
public function updateCompiledTemplate($cache_filename, $name) {
$source = $this->loader->getSource($name);
$compiled_source = $this->compileSource($source, $name);
$this->storage()->save($cache_filename, $compiled_source);
// Save the last modification time
......@@ -105,22 +95,6 @@ public function updateCompiledTemplate($cache_filename, $name, $inline = FALSE)
$this->cache_object->set($cid, REQUEST_TIME);
}
/**
* Gets the Loader instance.
*
* @param bool $inline
* TRUE, if the string loader is requested.
*
* @return \Twig_LoaderInterface
* A Twig_LoaderInterface instance
*/
public function getLoader($inline = FALSE) {
if (!isset($this->loader)) {
throw new \LogicException('You must set a loader first.');
}
return $inline ? $this->stringLoader : $this->loader;
}
/**
* Implements Twig_Environment::loadTemplate().
*
......@@ -133,8 +107,6 @@ public function getLoader($inline = FALSE) {
* The template name or the string which should be rendered as template.
* @param int $index
* The index if it is an embedded template.
* @param bool $inline
* TRUE, if the $name is a rendered template.
*
* @return \Twig_TemplateInterface
* A template instance representing the given template name.
......@@ -144,8 +116,8 @@ public function getLoader($inline = FALSE) {
* @throws \Twig_Error_Syntax
* When an error occurred during compilation.
*/
public function loadTemplate($name, $index = NULL, $inline = FALSE) {
$cls = $this->getTemplateClass($name, $index, $inline);
public function loadTemplate($name, $index = NULL) {
$cls = $this->getTemplateClass($name, $index);
if (isset($this->loadedTemplates[$cls])) {
return $this->loadedTemplates[$cls];
......@@ -155,7 +127,7 @@ public function loadTemplate($name, $index = NULL, $inline = FALSE) {
$cache_filename = $this->getCacheFilename($name);
if ($cache_filename === FALSE) {
$compiled_source = $this->compileSource($this->getLoader($inline)->getSource($name), $name);
$compiled_source = $this->compileSource($this->loader->getSource($name), $name);
eval('?' . '>' . $compiled_source);
}
else {
......@@ -163,11 +135,11 @@ public function loadTemplate($name, $index = NULL, $inline = FALSE) {
// If autoreload is on, check that the template has not been
// modified since the last compilation.
if ($this->isAutoReload() && !$this->isFresh($cache_filename, $name)) {
$this->updateCompiledTemplate($cache_filename, $name, $inline);
$this->updateCompiledTemplate($cache_filename, $name);
}
if (!$this->storage()->load($cache_filename)) {
$this->updateCompiledTemplate($cache_filename, $name, $inline);
$this->updateCompiledTemplate($cache_filename, $name);
$this->storage()->load($cache_filename);
}
}
......@@ -199,20 +171,18 @@ protected function storage() {
* The name for which to calculate the template class name.
* @param int $index
* The index if it is an embedded template.
* @param bool $inline
* TRUE, if the $name is a rendered template.
*
* @return string
* The template class name.
*/
public function getTemplateClass($name, $index = NULL, $inline = FALSE) {
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] = $this->templateClassPrefix . hash('sha256', $this->getLoader($inline)->getCacheKey($name)) . (NULL === $index ? '' : '_' . $index);
$this->templateClasses[$cache_index] = $this->templateClassPrefix . hash('sha256', $this->loader->getCacheKey($name)) . (NULL === $index ? '' : '_' . $index);
}
return $this->templateClasses[$cache_index];
}
......@@ -238,7 +208,7 @@ public function getTemplateClass($name, $index = NULL, $inline = FALSE) {
* The rendered inline template.
*/
public function renderInline($template_string, array $context = array()) {
return $this->loadTemplate($template_string, NULL, TRUE)->render($context);
return $this->loadTemplate($template_string, NULL)->render($context);
}
}
......@@ -8,6 +8,7 @@
namespace Drupal\system\Tests\Theme;
use Drupal\Component\Utility\String;
use Drupal\Core\Site\Settings;
use Drupal\simpletest\KernelTestBase;
/**
......@@ -42,6 +43,26 @@ public function testInlineTemplate() {
'#context' => array('unsafe_content' => $unsafe_string),
);
$this->assertEqual(drupal_render($element), 'test-with-context ' . String::checkPlain($unsafe_string));
// Enable twig_auto_reload and twig_debug.
$settings = Settings::getAll();
$settings['twig_debug'] = TRUE;
$settings['twig_auto_reload'] = TRUE;
new Settings($settings);
$this->container = $this->kernel->rebuildContainer();
\Drupal::setContainer($this->container);
$element = array();
$element['test'] = array(
'#type' => 'inline_template',
'#template' => 'test-with-context {{ lama }}',
'#context' => array('lama' => 'muuh'),
);
$element_copy = $element;
// Render it twice so that twig caching is triggered.
$this->assertEqual(drupal_render($element), 'test-with-context muuh');
$this->assertEqual(drupal_render($element_copy), 'test-with-context muuh');
}
}
......
......@@ -118,4 +118,20 @@ function testTwigCacheOverride() {
$this->assertFalse($new_cache_filename, 'Twig environment does not return cache filename after caching is disabled.');
}
/**
* Tests twig inline templates with auto_reload.
*/
public function testTwigInlineWithAutoReload() {
$parameters = $this->container->getParameter('twig.config');
$parameters['auto_reload'] = TRUE;
$parameters['debug'] = TRUE;
$this->setContainerParameter('twig.config', $parameters);
$this->rebuildContainer();
$this->drupalGet('theme-test/inline-template-test');
$this->assertResponse(200);
$this->drupalGet('theme-test/inline-template-test');
$this->assertResponse(200);
}
}
......@@ -59,6 +59,22 @@ public function testTemplate() {
return _theme('theme_test_template_test');
}
/**
* Tests the inline template functionality.
*
* @return array
* A render array containing an inline template.
*/
public function testInlineTemplate() {
$element = array();
$element['test'] = array(
'#type' => 'inline_template',
'#template' => 'test-with-context {{ lama }}',
'#context' => array('lama' => 'muuh'),
);
return $element;
}
/**
* Calls a theme hook suggestion.
*
......
......@@ -21,6 +21,13 @@ theme_test.template_test:
requirements:
_access: 'TRUE'
theme_test.inline_template_test:
path: '/theme-test/inline-template-test'
defaults:
_content: '\Drupal\theme_test\ThemeTestController::testInlineTemplate'
requirements:
_access: 'TRUE'
theme_test.suggestion:
path: '/theme-test/suggestion'
options:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment