From f3de043d0eabd7d5369414fa1e3d3d99b0418d79 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 26 Dec 2011 09:35:38 +0100 Subject: [PATCH] changed hash key expression support (expression must now be enclosed with parentheses and hash keys can now be names) --- CHANGELOG | 1 + doc/templates.rst | 21 ++++++++++++++++++--- lib/Twig/ExpressionParser.php | 18 +++++++++++++++++- test/Twig/Tests/Fixtures/expressions/array.test | 8 +++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 77be635..8f558ce 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 1.5.0 + * removed the need to quote hash keys * allowed hash keys to be any expression * added a do tag * added a flush tag diff --git a/doc/templates.rst b/doc/templates.rst index 9e4fd29..8bafe64 100644 --- a/doc/templates.rst +++ b/doc/templates.rst @@ -458,6 +458,9 @@ even if you're not working with PHP you should feel comfortable with it. Literals ~~~~~~~~ +.. versionadded:: 1.5 + Support for hash keys as names and expressions was added in Twig 1.5. + The simplest form of expressions are literals. Literals are representations for PHP types such as strings, numbers, and arrays. The following literals exist: @@ -475,9 +478,21 @@ exist: separated by a comma (``,``) and wrapped with squared brackets (``[]``). * ``{"foo": "bar"}``: Hashes are defined by a list of keys and values - separated by a comma (``,``) and wrapped with curly braces (``{}``). A value - can be any valid expression (as of Twig 1.5, keys can also be any valid - expression). + separated by a comma (``,``) and wrapped with curly braces (``{}``): + + .. node-block:: jinja + + # keys as string + { 'foo': 'foo', 'bar': 'bar' } + + # keys as names (equivalent to the previous hash) -- as of Twig 1.5 + { foo: 'foo', bar: 'bar' } + + # keys as integer + { 2: 'foo', 4: 'bar' } + + # keys as expressions (the expression must be enclosed into parentheses) -- as of Twig 1.5 + { (1 + 1): 'foo', (a ~ 'b'): 'bar' } * ``true`` / ``false``: ``true`` represents the true value, ``false`` represents the false value. diff --git a/lib/Twig/ExpressionParser.php b/lib/Twig/ExpressionParser.php index 25289fc..e9ed43a 100644 --- a/lib/Twig/ExpressionParser.php +++ b/lib/Twig/ExpressionParser.php @@ -236,7 +236,23 @@ class Twig_ExpressionParser } $first = false; - $key = $this->parseExpression(); + // a hash key can be: + // + // * a number -- 12 + // * a string -- 'a' + // * a name, which is equivalent to a string -- a + // * an expression, which must be enclosed in parentheses -- (1 + 2) + if ($stream->test(Twig_Token::STRING_TYPE) || $stream->test(Twig_Token::NAME_TYPE) || $stream->test(Twig_Token::NUMBER_TYPE)) { + $token = $stream->next(); + $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); + } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { + $key = $this->parseExpression(); + } else { + $current = $stream->getCurrent(); + + throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine()); + } + $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); $value = $this->parseExpression(); diff --git a/test/Twig/Tests/Fixtures/expressions/array.test b/test/Twig/Tests/Fixtures/expressions/array.test index 5b81a0e..c69b119 100644 --- a/test/Twig/Tests/Fixtures/expressions/array.test +++ b/test/Twig/Tests/Fixtures/expressions/array.test @@ -9,6 +9,9 @@ Twig supports array notation {{ {0: 1, 'foo': 'bar'}|join(',') }} {{ {0: 1, 'foo': 'bar'}|keys|join(',') }} +{{ {0: 1, foo: 'bar'}|join(',') }} +{{ {0: 1, foo: 'bar'}|keys|join(',') }} + {# nested arrays #} {% set a = [1, 2, [1, 2], {'foo': {'foo': 'bar'}}] %} {{ a[2]|join(',') }} @@ -31,7 +34,7 @@ Twig supports array notation {# keys can be any expression #} {% set a = 1 %} {% set b = "foo" %} -{% set ary = { a: 'a', b: 'b', 'c': 'c', a~b: 'd' } %} +{% set ary = { (a): 'a', (b): 'b', 'c': 'c', (a ~ b): 'd' } %} {{ ary|keys|join(',') }} {{ ary|join(',') }} --DATA-- @@ -42,6 +45,9 @@ foo,bar 1,bar 0,foo +1,bar +0,foo + 1,2 bar -- 1.7.2.5