From c8f67b6061df3d0a6af1344f69ad72f89c41c0f5 Mon Sep 17 00:00:00 2001 From: fabien Date: Tue, 27 Oct 2009 16:31:56 +0000 Subject: [PATCH] made the set tag more powerful git-svn-id: http://svn.twig-project.org/trunk@103 93ef8e89-cb99-4229-a87c-7fa0fa45744b --- doc/02-Twig-for-Template-Designers.markdown | 2 +- doc/04-Extending-Twig.markdown | 12 ++++++++- lib/Twig/Node/Set.php | 33 ++++++++++++++++++++------ lib/Twig/TokenParser/Set.php | 9 +++++- test/fixtures/tags/set/basic.test | 17 ++++++++++++++ test/unit/integrationTest.php | 2 +- 6 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 test/fixtures/tags/set/basic.test diff --git a/doc/02-Twig-for-Template-Designers.markdown b/doc/02-Twig-for-Template-Designers.markdown index 876d8eb..d9de144 100644 --- a/doc/02-Twig-for-Template-Designers.markdown +++ b/doc/02-Twig-for-Template-Designers.markdown @@ -507,7 +507,7 @@ the `set` tag and can have multiple targets: [twig] {% set foo as 'foo' %} - {% set key, value as call_something() %} + {% set foo, bar as 'foo', 'bar' %} ### Extends diff --git a/doc/04-Extending-Twig.markdown b/doc/04-Extending-Twig.markdown index e8041ad..fa6dc5f 100644 --- a/doc/04-Extending-Twig.markdown +++ b/doc/04-Extending-Twig.markdown @@ -152,12 +152,18 @@ Let's create a simple `set` tag that allows the definition of simple variables from within a template. The tag can be used like follows: [twig] - {% set name "value" %} + {% set name as "value" %} {{ name }} {# should output value #} +>**NOTE** +>The `set` tag is part of the Core extension and as such is always available. +>The built-in version is slightly more powerful and supports multiple +>assignments by defaults (cf. template designers chapter for more +>information). + First, we need to create a `Twig_TokenParser` class which will be able to parse this new language construct: @@ -189,6 +195,7 @@ Now, let's see the actual code of the token parser class: { $lineno = $token->getLine(); $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); + $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, 'as'); $value = $this->parser->getExpressionParser()->parseExpression(); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); @@ -212,7 +219,8 @@ stream (`$this->parser->getStream()`): returns it. * `expect()`: Expects a token and returns it (like `test()`) or throw a - syntax error if not found. + syntax error if not found (the second argument is the expected value of the + token). * `look()`: Looks a the next token. This is how you can have a look at the next token without consume it. diff --git a/lib/Twig/Node/Set.php b/lib/Twig/Node/Set.php index 6e3503b..0d367c6 100644 --- a/lib/Twig/Node/Set.php +++ b/lib/Twig/Node/Set.php @@ -3,16 +3,16 @@ class Twig_Node_Set extends Twig_Node { protected $names; - protected $value; + protected $values; protected $isMultitarget; - public function __construct($isMultitarget, $names, Twig_Node_Expression $value, $lineno, $tag = null) + public function __construct($isMultitarget, $names, $values, $lineno, $tag = null) { parent::__construct($lineno, $tag); $this->isMultitarget = $isMultitarget; $this->names = $names; - $this->value = $value; + $this->values = $values; } public function compile($compiler) @@ -46,10 +46,27 @@ class Twig_Node_Set extends Twig_Node ; } - $compiler - ->raw(' = ') - ->subcompile($this->value) - ->raw(";\n") - ; + $compiler->raw(' = '); + + if ($this->isMultitarget) + { + $compiler->write('array('); + foreach ($this->values as $idx => $value) + { + if ($idx) + { + $compiler->raw(', '); + } + + $compiler->subcompile($value); + } + $compiler->raw(')'); + } + else + { + $compiler->subcompile($this->values); + } + + $compiler->raw(";\n"); } } diff --git a/lib/Twig/TokenParser/Set.php b/lib/Twig/TokenParser/Set.php index e31d1e6..8ab170e 100644 --- a/lib/Twig/TokenParser/Set.php +++ b/lib/Twig/TokenParser/Set.php @@ -7,11 +7,16 @@ class Twig_TokenParser_Set extends Twig_TokenParser $lineno = $token->getLine(); list($isMultitarget, $names) = $this->parser->getExpressionParser()->parseAssignmentExpression(); $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, 'as'); - $value = $this->parser->getExpressionParser()->parseExpression(); + list(, $values) = $this->parser->getExpressionParser()->parseAssignmentExpression(); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - return new Twig_Node_Set($isMultitarget, $names, $value, $lineno, $this->getTag()); + if (count($names) !== count($values)) + { + throw new Twig_SyntaxError("When using set, you must have the same number of variables and assignements.", $lineno); + } + + return new Twig_Node_Set($isMultitarget, $names, $values, $lineno, $this->getTag()); } public function getTag() diff --git a/test/fixtures/tags/set/basic.test b/test/fixtures/tags/set/basic.test new file mode 100644 index 0000000..9c6fbd1 --- /dev/null +++ b/test/fixtures/tags/set/basic.test @@ -0,0 +1,17 @@ +--TEST-- +"set" tag +--TEMPLATE-- +{% set foo as 'foo' %} + +{{ foo }} + +{% set foo, bar as 'foo', 'bar' %} + +{{ foo }}{{ bar }} +--DATA-- +return array() +--EXPECT-- +foo + + +foobar diff --git a/test/unit/integrationTest.php b/test/unit/integrationTest.php index 48f3b0f..e34bf4d 100644 --- a/test/unit/integrationTest.php +++ b/test/unit/integrationTest.php @@ -35,7 +35,7 @@ class Foo } } -$t = new LimeTest(48); +$t = new LimeTest(49); $fixturesDir = realpath(dirname(__FILE__).'/../fixtures/'); foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) -- 1.7.2.5