mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-31 04:27:00 +00:00
Tweak null-safe operator implementation
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# 3.23.0 (2026-XX-XX)
|
||||
|
||||
* Add `?.` null-safe operator
|
||||
* Add `===` and `!==` operators (equivalent to the `same as` and `not same as` tests)
|
||||
|
||||
# 3.22.2 (2025-12-14)
|
||||
|
||||
@@ -23,9 +23,13 @@ $output = fopen(dirname(__DIR__).'/doc/operators_precedence.rst', 'w');
|
||||
$twig = new Environment(new ArrayLoader([]));
|
||||
$descriptionLength = 11;
|
||||
$expressionParsers = [];
|
||||
$seen = new SplObjectStorage();
|
||||
foreach ($twig->getExpressionParsers() as $expressionParser) {
|
||||
$expressionParsers[] = $expressionParser;
|
||||
$descriptionLength = max($descriptionLength, $expressionParser instanceof ExpressionParserDescriptionInterface ? strlen($expressionParser->getDescription()) : '');
|
||||
if (!$seen->offsetExists($expressionParser)) {
|
||||
$expressionParsers[] = $expressionParser;
|
||||
$seen->offsetSet($expressionParser, true);
|
||||
$descriptionLength = max($descriptionLength, $expressionParser instanceof ExpressionParserDescriptionInterface ? strlen($expressionParser->getDescription()) : '');
|
||||
}
|
||||
}
|
||||
|
||||
fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n");
|
||||
@@ -46,9 +50,13 @@ foreach ($expressionParsers as $expressionParser) {
|
||||
if ($previousPrecedence !== $precedence) {
|
||||
$previous = null;
|
||||
}
|
||||
$operatorName = '``'.$expressionParser->getName().'``';
|
||||
if ($expressionParser->getAliases()) {
|
||||
$operatorName .= ', ``'.implode('``, ``', $expressionParser->getAliases()).'``';
|
||||
}
|
||||
fwrite($output, rtrim(sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n",
|
||||
(!$previous || $previousPrecedence !== $precedence ? $precedence : '').($expressionParser->getPrecedenceChange() ? ' => '.$expressionParser->getPrecedenceChange()->getNewPrecedence() : ''),
|
||||
'``'.$expressionParser->getName().'``',
|
||||
$operatorName,
|
||||
!$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '',
|
||||
!$previous || $previousAssociativity !== $associativity ? $associativity : '',
|
||||
$expressionParser instanceof ExpressionParserDescriptionInterface ? $expressionParser->getDescription() : '',
|
||||
@@ -83,9 +91,13 @@ foreach ($expressionParsers as $expressionParser) {
|
||||
if ($previousPrecedence !== $precedence) {
|
||||
$previous = null;
|
||||
}
|
||||
$operatorName = '``'.$expressionParser->getName().'``';
|
||||
if ($expressionParser->getAliases()) {
|
||||
$operatorName .= ', ``'.implode('``, ``', $expressionParser->getAliases()).'``';
|
||||
}
|
||||
fwrite($output, rtrim(sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n",
|
||||
!$previous || $previousPrecedence !== $precedence ? $precedence : '',
|
||||
'``'.$expressionParser->getName().'``',
|
||||
$operatorName,
|
||||
!$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '',
|
||||
!$previous || $previousAssociativity !== $associativity ? $associativity : '',
|
||||
$expressionParser instanceof ExpressionParserDescriptionInterface ? $expressionParser->getDescription() : '',
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``(`` | | | Twig function call |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``.`` | | | Get an attribute on a variable |
|
||||
| | ``.``, ``?.`` | | | Get an attribute on a variable |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``[`` | | | Array access |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
@@ -88,9 +88,7 @@
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| 10 | ``or`` | infix | Left | |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| 5 | ``?:`` | infix | Right | Elvis operator (a ?: b) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``?:`` | | | Elvis operator (a ?: b) |
|
||||
| 5 | ``?:``, ``? :`` | infix | Right | Elvis operator (a ?: b) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| 0 | ``(`` | prefix | n/a | Explicit group expression (a) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
@@ -110,7 +108,7 @@ Here is the same table for Twig 4.0 with adjusted precedences:
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``(`` | infix | Left | Twig function call |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``.`` | | | Get an attribute on a variable |
|
||||
| | ``.``, ``?.`` | | | Get an attribute on a variable |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``[`` | | | Array access |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
@@ -192,9 +190,7 @@ Here is the same table for Twig 4.0 with adjusted precedences:
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| 5 | ``??`` | infix | Right | Null coalescing operator (a ?? b) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``?:`` | | | Elvis operator (a ?: b) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| | ``?:`` | | | Elvis operator (a ?: b) |
|
||||
| | ``?:``, ``? :`` | | | Elvis operator (a ?: b) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
| 0 | ``(`` | prefix | n/a | Explicit group expression (a) |
|
||||
+------------+------------------+---------+---------------+-------------------------------------------------------------------+
|
||||
|
||||
+26
-3
@@ -865,7 +865,7 @@ The following operators don't fit into any of the other categories:
|
||||
|
||||
.. _dot_operator:
|
||||
|
||||
* ``.``, ``[]``: Gets an attribute of a variable.
|
||||
* ``.``, ``?.``, ``[]``: Gets an attribute of a variable.
|
||||
|
||||
The (``.``) operator abstracts getting an attribute of a variable (methods,
|
||||
properties or constants of a PHP object, or items of a PHP array):
|
||||
@@ -874,8 +874,23 @@ The following operators don't fit into any of the other categories:
|
||||
|
||||
{{ user.name }}
|
||||
|
||||
After the ``.``, you can use any expression by wrapping it with parenthesis
|
||||
``()``.
|
||||
The null-safe operator (``?.``) works like the dot operator but returns
|
||||
``null`` instead of throwing an exception when the left operand is ``null``:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{{ user?.name }}
|
||||
{# returns null if user is null, otherwise returns user.name #}
|
||||
|
||||
{{ user?.address?.city }}
|
||||
{# can be chained for safe navigation through potentially null values #}
|
||||
|
||||
.. versionadded:: 3.23
|
||||
|
||||
The null-safe operator was added in Twig 3.23.
|
||||
|
||||
After the ``.`` or ``?.``, you can use any expression by wrapping it with
|
||||
parenthesis ``()``.
|
||||
|
||||
One use case is when the attribute contains special characters (like ``-``
|
||||
that would be interpreted as the minus operator):
|
||||
@@ -884,6 +899,7 @@ The following operators don't fit into any of the other categories:
|
||||
|
||||
{# equivalent to the non-working user.first-name #}
|
||||
{{ user.('first-name') }}
|
||||
{{ user?.('first-name') }}
|
||||
|
||||
Another use case is when the attribute is "dynamic" (defined via a variable):
|
||||
|
||||
@@ -891,6 +907,7 @@ The following operators don't fit into any of the other categories:
|
||||
|
||||
{{ user.(name) }}
|
||||
{{ user.('get' ~ name) }}
|
||||
{{ user?.(name) }}
|
||||
|
||||
Before Twig 3.15, use the :doc:`attribute <functions/attribute>` function
|
||||
instead for the two previous use cases.
|
||||
@@ -926,6 +943,12 @@ The following operators don't fit into any of the other categories:
|
||||
* if not, and if ``strict_variables`` is ``false``, return ``null``;
|
||||
* if not, throw an exception.
|
||||
|
||||
To resolve ``user?.name`` to a PHP call, Twig checks if ``user`` is
|
||||
``null`` first:
|
||||
|
||||
* if ``user`` is ``null``, return ``null``;
|
||||
* otherwise, use the same algorithm as for ``user.name``.
|
||||
|
||||
To resolve ``user['name']`` to a PHP call, Twig uses the following algorithm
|
||||
at runtime:
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
* (c) Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
||||
Reference in New Issue
Block a user