diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php index 846174d..3967cf8 100644 --- a/core/lib/Drupal/Core/Template/Attribute.php +++ b/core/lib/Drupal/Core/Template/Attribute.php @@ -99,6 +99,14 @@ protected function createAttributeValue($name, $value) { elseif (!is_object($value)) { $value = new AttributeString($name, $value); } + // Provide a better exception message when invalid object is passed as value. + elseif (is_object($value) && !method_exists($value, '__toString')) { + throw new \Exception(t('"@attribute_name" attribute value of type "@class" can not be converted to string', array( + '@attribute_name' => $name, + '@class' => get_class($value) + ))); + } + return $value; } diff --git a/core/lib/Drupal/Core/Template/TwigNodeExpressionFunction.php b/core/lib/Drupal/Core/Template/TwigNodeExpressionFunction.php new file mode 100644 index 0000000..3902abd --- /dev/null +++ b/core/lib/Drupal/Core/Template/TwigNodeExpressionFunction.php @@ -0,0 +1,51 @@ +extra_arguments = $extra_arguments; + } + + /** + * {@inheritdoc} + */ + public function compile(\Twig_Compiler $compiler) { + $name = $this->getAttribute('name'); + $function = $compiler->getEnvironment()->getFunction($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'function'); + $this->setAttribute('thing', $function); + $this->setAttribute('needs_environment', $function->needsEnvironment()); + $this->setAttribute('needs_context', $function->needsContext()); + $this->setAttribute('arguments', array_merge($function->getArguments(), $this->extra_arguments)); + if ($function instanceof \Twig_FunctionCallableInterface || $function instanceof \Twig_SimpleFunction) { + $this->setAttribute('callable', $function->getCallable()); + } + + $this->compileCallable($compiler); + } +} + diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php index 4915c16..d4095a4 100644 --- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php +++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php @@ -39,8 +39,9 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { } $class = get_class($node); $line = $node->getLine(); + $name = $node->getNode('expr')->hasAttribute('name') ? $node->getNode('expr')->getAttribute('name') : 'Object'; return new $class( - new \Twig_Node_Expression_Function('render_var', new \Twig_Node(array($node->getNode('expr'))), $line), + new TwigNodeExpressionFunction('render_var', new \Twig_Node(array($node->getNode('expr'))), array($name), $line), $line ); } diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index e0cfcc2..c20da07 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -119,7 +119,7 @@ function twig_render_template($template_file, $variables) { * @see render * @see TwigNodeVisitor */ -function twig_render_var($arg) { +function twig_render_var($arg_name, $arg) { // Check for numeric zero. if ($arg === 0) { return 0; @@ -144,7 +144,7 @@ function twig_render_var($arg) { return (string) $arg; } else { - throw new Exception(t('Object of type "@class" cannot be printed.', array('@class' => get_class($arg)))); + throw new Exception(t('@arg_name of type "@class" doesn\'t implement __toString.', array('@arg_name' => $arg_name, '@class' => get_class($arg)))); } }