mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-21 14:01:46 +00:00
Add support for renaming variables in object destructuring
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 3.24.0 (2026-XX-XX)
|
||||
|
||||
* n/a
|
||||
* Add support for renaming variables in object destructuring (`{name: userName} = user`)
|
||||
|
||||
# 3.23.0 (2026-01-23)
|
||||
|
||||
|
||||
@@ -1160,6 +1160,30 @@ or mapping by extracting values based on property/key names:
|
||||
{{ name }} {# user.name #}
|
||||
{{ email }} {# user.email #}
|
||||
|
||||
You can rename variables during destructuring by using the ``key: variable``
|
||||
syntax, where the key is the property to extract and the variable is the name
|
||||
to assign to:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{% do {name: userName, email: userEmail} = user %}
|
||||
|
||||
{{ userName }} {# user.name #}
|
||||
{{ userEmail }} {# user.email #}
|
||||
|
||||
This is especially useful when you need to destructure multiple objects that
|
||||
share the same property names:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{% do {data: product, error: productError} = loadProduct() %}
|
||||
{% do {data: stock, error: stockError} = loadStock() %}
|
||||
|
||||
{{ product }} {# loadProduct().data #}
|
||||
{{ productError }} {# loadProduct().error #}
|
||||
{{ stock }} {# loadStock().data #}
|
||||
{{ stockError }} {# loadStock().error #}
|
||||
|
||||
.. note::
|
||||
|
||||
Object destructuring uses the :ref:`dot operator <dot_operator>` to access
|
||||
|
||||
@@ -23,7 +23,8 @@ use Twig\Node\Node;
|
||||
*/
|
||||
class ObjectDestructuringSetBinary extends AbstractBinary
|
||||
{
|
||||
private array $properties = [];
|
||||
/** @var list<array{property: string, variable: string}> */
|
||||
private array $mappings = [];
|
||||
|
||||
/**
|
||||
* @param ArrayExpression $left The array expression containing object/mapping destructuring properties
|
||||
@@ -38,7 +39,11 @@ class ObjectDestructuringSetBinary extends AbstractBinary
|
||||
if (!$pair['value'] instanceof ContextVariable) {
|
||||
throw new SyntaxError(\sprintf('Cannot assign to "%s", only variables can be assigned in object/mapping destructuring.', $pair['value']::class), $lineno);
|
||||
}
|
||||
$this->properties[] = $pair['value']->getAttribute('name');
|
||||
|
||||
$this->mappings[] = [
|
||||
'property' => $pair['key']->getAttribute('value'),
|
||||
'variable' => $pair['value']->getAttribute('name'),
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($left, $right, $lineno);
|
||||
@@ -48,18 +53,18 @@ class ObjectDestructuringSetBinary extends AbstractBinary
|
||||
{
|
||||
$compiler->addDebugInfo($this);
|
||||
$compiler->raw('[');
|
||||
foreach ($this->properties as $i => $property) {
|
||||
foreach ($this->mappings as $i => $mapping) {
|
||||
if ($i) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->raw('$context[')->repr($property)->raw(']');
|
||||
$compiler->raw('$context[')->repr($mapping['variable'])->raw(']');
|
||||
}
|
||||
$compiler->raw('] = [');
|
||||
foreach ($this->properties as $i => $property) {
|
||||
foreach ($this->mappings as $i => $mapping) {
|
||||
if ($i) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ')->subcompile($this->getNode('right'))->raw(', ')->repr($property)->raw(', [], \\Twig\\Template::ANY_CALL, false, false, false, ')->repr($this->getNode('right')->getTemplateLine())->raw(')');
|
||||
$compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ')->subcompile($this->getNode('right'))->raw(', ')->repr($mapping['property'])->raw(', [], \\Twig\\Template::ANY_CALL, false, false, false, ')->repr($this->getNode('right')->getTemplateLine())->raw(')');
|
||||
}
|
||||
$compiler->raw(']');
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@ Twig supports the "=" operator (assignment)
|
||||
{% do {name, email} = user %}{{ name }} {{ email }}
|
||||
{% do {first_name, last_name} = user_map %}{{ first_name }} {{ last_name }}
|
||||
{% do {name} = user_obj %}{{ name }}
|
||||
|
||||
# Object destructuring with renaming
|
||||
{% do {name: userName, email: userEmail} = user %}{{ userName }} {{ userEmail }}
|
||||
{% do {first_name: first, last_name: last} = user_map %}{{ first }} {{ last }}
|
||||
{% do {name: objName} = user_obj %}{{ objName }}
|
||||
{% do {name: n1} = user %}{% do {name: n2} = user_obj %}{{ n1 }} {{ n2 }}
|
||||
--DATA--
|
||||
return [
|
||||
'user' => (object)['name' => 'Fabien', 'email' => 'fabien@example.com'],
|
||||
@@ -47,3 +53,9 @@ one two null
|
||||
Fabien fabien@example.com
|
||||
Fabien Potencier
|
||||
Fabien
|
||||
|
||||
# Object destructuring with renaming
|
||||
Fabien fabien@example.com
|
||||
Fabien Potencier
|
||||
Fabien
|
||||
Fabien Fabien
|
||||
|
||||
Reference in New Issue
Block a user