diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 2b06429..ecb44d2 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -494,6 +494,9 @@ function _theme($hook, $variables = array()) { } elseif (!empty($info['render element'])) { $variables += array($info['render element'] => array()); + + // Declare render variables. + $variables['theme_render_variables'][] = $info['render element']; } // Supply original caller info. $variables += array( @@ -1911,6 +1914,9 @@ function _template_preprocess_default_variables() { $variables['db_is_active'] = FALSE; } + $variables['theme_render_variables'][] = 'title_prefix'; + $variables['theme_render_variables'][] = 'title_suffix'; + // Give modules a chance to alter the default template variables. \Drupal::moduleHandler()->alter('template_preprocess_default_variables', $variables); diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index c671899..bd86df1 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -22,6 +22,7 @@ class TwigEnvironment extends \Twig_Environment { protected $cache_object = NULL; protected $storage = NULL; + protected $dynamic_vars = array(); /** * Static cache of template classes. @@ -126,6 +127,29 @@ public function loadTemplate($name, $index = NULL) { } /** + * @todo + * + * @param array $vars @todo + * @param string $name @todo + */ + public function setDynamicVars($vars, $name) { + $this->dynamic_vars[$name] = $vars; + } + + /** + * @todo + * + * @param string $name @todo + * @return string @todo + */ + public function getDynamicVars($name) { + if (isset($this->dynamic_vars[$name])) { + return $this->dynamic_vars[$name]; + } + return NULL; + } + + /** * Gets the PHP code storage object to use for the compiled Twig files. * * @return \Drupal\Component\PhpStorage\PhpStorageInterface diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php index a24ee50..10ce0a0 100644 --- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php +++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php @@ -19,9 +19,42 @@ class TwigNodeVisitor implements \Twig_NodeVisitorInterface { /** - * {@inheritdoc} + * TRUE when this node is a function getting arguments by reference. + * + * For example: 'hide' or 'render' are such functions. + * + * @var bool + */ + protected $isReference = FALSE; + protected $dynamic_vars = array(); + + /** + * Implements Twig_NodeVisitorInterface::enterNode(). */ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) { + if ($node instanceof \Twig_Node_Module) { + $filename = $node->getAttribute('filename'); + $this->dynamic_vars = $env->getDynamicVars($filename); + } + + if ($node instanceof \Twig_Node_Expression_Function) { + $name = $node->getAttribute('name'); + $func = $env->getFunction($name); + + // Optimization: Do not support nested functions. + if ($this->isReference && $func instanceof \Twig_Function_Function) { + $this->isReference = FALSE; + } + if ($func instanceof TwigReferenceFunction) { + // We need to create a TwigReference + $this->isReference = TRUE; + } + } + if ($node instanceof \Twig_Node_Print && $this->isReference) { + // Our injected render_var needs arguments passed by reference -- in case of render array + $this->isReference = TRUE; + } + return $node; } @@ -40,6 +73,20 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { ); } + if ($this->isReference) { + if ($node instanceof \Twig_Node_Expression_Name) { + $name = $node->getAttribute('name'); + if (!isset($this->dynamic_vars['render_variables']) || in_array($name, $this->dynamic_vars['render_variables'])) { + return new TwigNodeExpressionNameReference($name, $node->getLine()); + } + $this->isReference = FALSE; + } + elseif ($node instanceof \Twig_Function_Function) { + // Do something! + $this->isReference = FALSE; + } + } + return $node; } diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index 1595bf8..756c77d 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -45,7 +45,14 @@ function twig_init(Extension $theme) { * The output generated by the template, plus any debug information. */ function twig_render_template($template_file, $variables) { - $twig_service = \Drupal::service('twig'); + $variables['_references'] = array(); + + $twig = Drupal::service('twig'); + $dynamic_vars = array( + 'render_variables' => $variables['theme_render_variables'], + ); + $twig->setDynamicVars($dynamic_vars, $template_file); + $output = array( 'debug_prefix' => '', 'debug_info' => '',