mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-31 12:37:15 +00:00
feature #3255 Make round brackets optional for one argument tests like sameas (iquito)
This PR was submitted for the 3.x branch but it was squashed and merged into the 1.x branch instead.
Discussion
----------
Make round brackets optional for one argument tests like sameas
Currently Twig forces round brackets when doing tests with `is` if there is an argument:
{{ 1 is same as(1) ? 'OK' }}
{{ 8 is divisible by(2) ? 'OK' }}
That syntax always bumped me, because without the brackets it would be easier to understand and write, especially for people who do not know Twig internals:
{{ 1 is same as 1 ? 'OK' }}
{{ 8 is divisible by 2 ? 'OK' }}
Twig only has the `same as` and `divisible by` tests which need arguments (in the base library), and for both you usually only need one argument, so it could make the template syntax more concise. [Jinja already supports this syntax](https://jinja.palletsprojects.com/en/2.11.x/templates/#tests) for one argument tests, so it would be one less difference between Jinja and Twig for people who use both.
The changes in this pull request should be fully backwards-compatible - instead of Twig throwing a SyntaxError it now accepts one argument when the round brackets are missing. I added an option for TwigTest to signal that there is one mandatory argument for the test, otherwise the ExpressionParser does not know it should look for that mandatory argument, and this feature is therefore available to anybody writing their own TwigTests, which could help extensions to Twig to simplify their syntax too.
I also adjusted the unit tests for `sameas` and `divisibleby` in hopefully a sensible way.
Commits
-------
1ee72d9e Make round brackets optional for one argument tests like sameas
This commit is contained in:
@@ -711,6 +711,8 @@ class ExpressionParser
|
||||
$arguments = null;
|
||||
if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
|
||||
$arguments = $this->parseArguments(true);
|
||||
} elseif ($test->hasOneMandatoryArgument()) {
|
||||
$arguments = new Node([0 => $this->parsePrimaryExpression()]);
|
||||
}
|
||||
|
||||
return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
|
||||
|
||||
@@ -244,11 +244,11 @@ class CoreExtension extends AbstractExtension
|
||||
new TwigTest('odd', null, ['node_class' => '\Twig\Node\Expression\Test\OddTest']),
|
||||
new TwigTest('defined', null, ['node_class' => '\Twig\Node\Expression\Test\DefinedTest']),
|
||||
new TwigTest('sameas', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']),
|
||||
new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest']),
|
||||
new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'one_mandatory_argument' => true]),
|
||||
new TwigTest('none', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
|
||||
new TwigTest('null', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
|
||||
new TwigTest('divisibleby', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
|
||||
new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest']),
|
||||
new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'one_mandatory_argument' => true]),
|
||||
new TwigTest('constant', null, ['node_class' => '\Twig\Node\Expression\Test\ConstantTest']),
|
||||
new TwigTest('empty', 'twig_test_empty'),
|
||||
new TwigTest('iterable', 'twig_test_iterable'),
|
||||
|
||||
@@ -35,6 +35,7 @@ class TwigTest
|
||||
'node_class' => '\Twig\Node\Expression\TestExpression',
|
||||
'deprecated' => false,
|
||||
'alternative' => null,
|
||||
'one_mandatory_argument' => false,
|
||||
], $options);
|
||||
}
|
||||
|
||||
@@ -82,6 +83,11 @@ class TwigTest
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
public function hasOneMandatoryArgument(): bool
|
||||
{
|
||||
return (bool) $this->options['one_mandatory_argument'];
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig\TwigTest', 'Twig_SimpleTest');
|
||||
|
||||
@@ -179,8 +179,11 @@ class SandboxTest extends \PHPUnit\Framework\TestCase
|
||||
'is_defined' => ['{{ obj.anotherFooObject is defined }}', '1'],
|
||||
'is_null' => ['{{ obj is null }}', ''],
|
||||
'is_sameas' => ['{{ obj is same as(obj) }}', '1'],
|
||||
'is_sameas_no_brackets' => ['{{ obj is same as obj }}', '1'],
|
||||
'is_sameas_from_array' => ['{{ arr.obj is same as(arr.obj) }}', '1'],
|
||||
'is_sameas_from_array_no_brackets' => ['{{ arr.obj is same as arr.obj }}', '1'],
|
||||
'is_sameas_from_another_method' => ['{{ obj.anotherFooObject is same as(obj.anotherFooObject) }}', ''],
|
||||
'is_sameas_from_another_method_no_brackets' => ['{{ obj.anotherFooObject is same as obj.anotherFooObject }}', ''],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
Twig supports the "divisible by" operator
|
||||
--TEMPLATE--
|
||||
{{ 8 is divisible by(2) ? 'OK' }}
|
||||
{{ 8 is divisible by 2 ? 'OK' }}
|
||||
{{ 8 is not divisible by(3) ? 'OK' }}
|
||||
{{ 8 is divisible by (2) ? 'OK' }}
|
||||
{{ 8 is divisible by 2 ? 'OK' }}
|
||||
{{ 8 is not
|
||||
divisible
|
||||
by
|
||||
@@ -15,3 +17,5 @@ OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
Twig supports the "same as" operator
|
||||
--TEMPLATE--
|
||||
{{ 1 is same as(1) ? 'OK' }}
|
||||
{{ 1 is same as 1 ? 'OK' }}
|
||||
{{ 1 is not same as(true) ? 'OK' }}
|
||||
{{ 1 is not same as true ? 'OK' }}
|
||||
{{ 1 is same as(1) ? 'OK' }}
|
||||
{{ 1 is not same as(true) ? 'OK' }}
|
||||
{{ 1 is same as (1) ? 'OK' }}
|
||||
{{ 1 is same as 1 ? 'OK' }}
|
||||
{{ 1 is not same as '1' ? 'OK' }}
|
||||
{{ 1 is not
|
||||
same
|
||||
as
|
||||
@@ -19,3 +23,7 @@ OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
|
||||
Reference in New Issue
Block a user