diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 898fdf8..a9ecec7 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -23,9 +23,11 @@ public function getFunctions() { // @todo Remove URL function once http://drupal.org/node/1778610 is resolved. 'url' => new \Twig_Function_Function('url'), // These functions will receive a TwigReference object, if a render array is detected - 'hide' => new TwigReferenceFunction('twig_hide'), - 'render_var' => new TwigReferenceFunction('twig_render_var'), - 'show' => new TwigReferenceFunction('twig_show'), + 'hide' => new TwigReferenceFunction('twig_hide', array('needs_context' => TRUE)), +// 'change' => new TwigReferenceFunction('twig_change', array('needs_context' => TRUE)), + + 'render_var' => new TwigReferenceFunction('twig_render_var', array('needs_context' => TRUE)), + 'show' => new TwigReferenceFunction('twig_show', array('needs_context' => TRUE)), ); } @@ -39,7 +41,7 @@ public function getNodeVisitors() { // The node visitor is needed to wrap all variables with // render_var -> twig_render_var() function. return array( - new TwigNodeVisitor(), + new TwigNodeVisitor(), new TwigReferenceNodeVisitor() ); } diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php index 710faa0..2af494a 100644 --- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php +++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php @@ -31,23 +31,23 @@ class TwigNodeVisitor implements \Twig_NodeVisitorInterface { * Implements Twig_NodeVisitorInterface::enterNode(). */ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) { - 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) { - // Our injected render_var needs arguments passed by reference -- in case of render array - $this->isReference = TRUE; - } +// 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) { +// // Our injected render_var needs arguments passed by reference -- in case of render array +// $this->isReference = TRUE; +// } return $node; } @@ -62,7 +62,7 @@ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) { */ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { if ($node instanceof \Twig_Node_Print) { - $this->isReference = FALSE; +// $this->isReference = FALSE; $class = get_class($node); return new $class( @@ -71,16 +71,16 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { ); } - if ($this->isReference) { - if ($node instanceof \Twig_Node_Expression_Name) { - $name = $node->getAttribute('name'); - return new TwigNodeExpressionNameReference($name, $node->getLine()); - } - elseif ($node instanceof \Twig_Function_Function) { - // Do something! - $this->isReference = FALSE; - } - } +// if ($this->isReference) { +// if ($node instanceof \Twig_Node_Expression_Name) { +// $name = $node->getAttribute('name'); +// return new TwigNodeExpressionNameReference($name, $node->getLine()); +// } +// elseif ($node instanceof \Twig_Function_Function) { +// // Do something! +// $this->isReference = FALSE; +// } +// } return $node; } @@ -90,6 +90,6 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { */ function getPriority() { // We want to run before other NodeVisitors like Escape or Optimizer - return -1; + return -2; } } diff --git a/core/lib/Drupal/Core/Template/TwigReferenceNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigReferenceNodeVisitor.php index 38e8c3c..798b327 100644 --- a/core/lib/Drupal/Core/Template/TwigReferenceNodeVisitor.php +++ b/core/lib/Drupal/Core/Template/TwigReferenceNodeVisitor.php @@ -134,7 +134,7 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { * Implements Twig_NodeVisitorInterface::getPriority(). */ function getPriority() { - // We want to run before other NodeVisitors like Escape or Optimizer - return -2; + // This should come after TwigNodeVisitor. + return -1; } } diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index 1ba60a5..ec315bb 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -93,39 +93,39 @@ function twig_render_template($template_file, $variables) { * @see render * @see TwigNodeVisitor */ -function twig_render_var($arg) { - if ($arg instanceof TwigReference) { - $arg = &$arg->getReference(); +function twig_render_var(&$context, $template, $val) { + if (isset($val['#twig_reference']) && $val['#twig_reference'] === TRUE) { + $val = &$template->unwrapReference($context, $val); } // Check for numeric zero. - if ($arg === 0) { + if ($val === 0) { return 0; } // == is true also for empty arrays - if ($arg == NULL) { + if ($val == NULL) { return NULL; } // Keep Twig_Markup objects intact to prepare for later autoescaping support - if ($arg instanceOf Twig_Markup) { - return $arg; + if ($val instanceOf Twig_Markup) { + return $val; } - if (is_scalar($arg)) { - return $arg; + if (is_scalar($val)) { + return $val; } - if (is_object($arg)) { - if (method_exists($arg, '__toString')) { - return (string) $arg; + if (is_object($val)) { + if (method_exists($val, '__toString')) { + return (string) $val; } throw new Exception(t('Object of type "@class" cannot be printed.', array('@class' => get_class($arg)))); } // This is a normal render array. - return render($arg); + return render($val); } /** @@ -133,11 +133,12 @@ function twig_render_var($arg) { * * @see hide */ -function twig_hide($element) { - if ($element instanceof TwigReference) { - $element = &$element->getReference(); - hide($element); - } +function twig_hide(&$context, $template, $val) { + // Unwrap reference if twig_reference key is set + if (isset($val['#twig_reference']) && $val['#twig_reference'] === TRUE) { + $val = &$template->unwrapReference($context, $val); + } + hide($val); // @todo Add warning in else case } @@ -146,10 +147,11 @@ function twig_hide($element) { * * @see show */ -function twig_show($element) { - if ($element instanceof TwigReference) { - $element = &$element->getReference(); - show($element); +function twig_show(&$context, $template, $val) { + if (isset($val['#twig_reference']) && $val['#twig_reference'] === TRUE) { + $val = &$template->unwrapReference($context, $val); } + + show($element); // @todo Add warning in else case }