Commit Graph

7383 Commits

Author SHA1 Message Date
Fabien Potencier 0319c822d1 Update CHANGELOG 2026-02-08 19:02:26 +01:00
Fabien Potencier 751a187f07 feature #4748 Support short-circuiting in null-safe operator chains (HypeMC)
This PR was merged into the 3.x branch.

Discussion
----------

Support short-circuiting in null-safe operator chains

This PR adds short-circuiting for null-safe operator chains, using the same rules as PHP, `PropertyAccess`, and the `ExpressionLanguage`.

Previously, only the immediate null-safe access was guarded. With this change, as soon as a `null` is encountered at a null-safe access, the rest of the chain is skipped.

My approach was to move the null check outside of the `getAttribute()` calls so the expression can immediately return `null`, eg:

```twig
foo?.bar.baz
```

Before:

```php
yield $this->env
    ->getRuntime('Twig\Runtime\EscaperRuntime')
    ->escape(
        CoreExtension::getAttribute(
            $this->env,
            $this->source,
            (
                null === (
                    $_v0 = (
                        isset($context['foo']) || array_key_exists('foo', $context)
                            ? $context['foo']
                            : throw new RuntimeError('Variable "foo" does not exist.', 3, $this->source)
                    )
                )
                    ? null
                    : CoreExtension::getAttribute(
                        $this->env,
                        $this->source,
                        $_v0,
                        'bar',
                        [],
                        'any',
                        false,
                        false,
                        false,
                        3
                    )
            ),
            'baz',
            [],
            'any',
            false,
            false,
            false,
            3
        ),
        'html',
        null,
        true
    );
```

Now:

```php
yield $this->env
    ->getRuntime('Twig\Runtime\EscaperRuntime')
    ->escape(
        (
            null === (
                $_v0 = (
                    isset($context['foo']) || array_key_exists('foo', $context)
                        ? $context['foo']
                        : throw new RuntimeError('Variable "foo" does not exist.', 3, $this->source)
                )
            )
                ? null
                : CoreExtension::getAttribute(
                    $this->env,
                    $this->source,
                    CoreExtension::getAttribute(
                        $this->env,
                        $this->source,
                        $_v0,
                        'bar',
                        [],
                        'any',
                        false,
                        false,
                        false,
                        3
                    ),
                    'baz',
                    [],
                    'any',
                    false,
                    false,
                    false,
                    3
                )
        ),
        'html',
        null,
        true
    );
```

Commits
-------

d56e8e2dba Support short-circuiting in null-safe operator chains
2026-02-08 19:02:03 +01:00
Fabien Potencier afe8e19ecb feature #4743 Add html_attr_relaxed escaping strategy (mpdude)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Add `html_attr_relaxed` escaping strategy

This adds `html_attr_relaxed`, a relaxed variant of the `html_attr` escaping strategy. The difference is that `html_attr_relaxed` does not escape the `:`, `@`, `[` and `]` characters. These are used by some front-end frameworks in attribute names to wire special handling/value binding. See https://v2.vuejs.org/v2/guide/syntax.html#v-bind-Shorthand for an example.

The HTML 5 spec does not exclude all those characters from attribute names ([html.spec.whatwg.org/multipage/syntax.html#attributes-2](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2)).

However, at least XML processors will treat the colon as the XML namespace separator.

HTML 5 allows XML only on SVG and MathML elements, and only for pre-defined namespace-prefixes ([developer.mozilla.org/en-US/docs/Web/API/Attr/localName#:~:text=That means that the local,different from the qualified name](https://developer.mozilla.org/en-US/docs/Web/API/Attr/localName#:~:text=That%20means%20that%20the%20local,different%20from%20the%20qualified%20name)). For other something: prefixes, these will simply be passed on as part of the local attribute name.

According to [engine.sygnal.com/research/html5-attribute-names](https://engine.sygnal.com/research/html5-attribute-names), all current browser implementations handle at least the colon fine, and the aforementioned Vue.js documentation suggests that this is also the case for @.

Note also that Symfony UX only conditionally escapes attribute names, and it has `:` and `@` in its safe list:
https://github.com/symfony/ux/blob/c9a3e66b8ac53e870097e8a828913e57204398e7/src/TwigComponent/src/ComponentAttributes.php#L82

Closes #3614.

Commits
-------

04aa3df49f Add `html_attr_relaxed` escaping strategy
2026-02-08 18:59:10 +01:00
Matthias Pigulla 04aa3df49f Add html_attr_relaxed escaping strategy 2026-02-08 18:59:07 +01:00
Fabien Potencier df893829f2 feature #4759 Add support for renaming variables in object destructuring (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Add support for renaming variables in object destructuring

Closes #4747

Commits
-------

3cc1b5233c Add support for renaming variables in object destructuring
2026-02-07 14:22:40 +01:00
Fabien Potencier 5fabdd0e6c minor #4764 re-add mixed return type (xabbuh)
This PR was merged into the 3.x branch.

Discussion
----------

re-add mixed return type

re-doing #4582, see https://github.com/symfony/symfony/actions/runs/21779345389/job/62840897500#step:8:3635

Commits
-------

3a903664a8 re-add mixed return type
2026-02-07 13:53:57 +01:00
Christian Flothmann 3a903664a8 re-add mixed return type 2026-02-07 13:41:32 +01:00
Fabien Potencier 3e213d14f3 minor #4625 [Doc] Fix intro for operator precedence table ? (hellomedia)
This PR was merged into the 3.x branch.

Discussion
----------

[Doc] Fix intro for operator precedence table ?

The table introductory paragraph says operator with lowest precedence are listed first ( I assume it means "listed first in the operator table" ).

However, the table starts with a precedence of 500, which seems to be the highest.

Am I completely misreading this ?

Commits
-------

26a12f73f2 Fix intro for operator precedence table ?
2026-02-07 10:12:40 +01:00
Fabien Potencier f502c9ed60 minor #4745 Update .gitattributes to remove splitsh.json (williamdes)
This PR was merged into the 3.x branch.

Discussion
----------

Update .gitattributes to remove splitsh.json

- Updated .gitattributes to remove splitsh.json

Commits
-------

79aecfbae0 Update .gitattributes to remove splitsh.json
2026-02-07 10:09:51 +01:00
Fabien Potencier 44093544e6 Use stable versions of tools 2026-02-07 09:12:49 +01:00
Fabien Potencier 2c2d2fd435 minor #4762 Fix CS (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix CS

Commits
-------

861215c507 Fix CS
2026-02-07 09:10:10 +01:00
Fabien Potencier 861215c507 Fix CS 2026-02-07 09:07:38 +01:00
HypeMC d56e8e2dba Support short-circuiting in null-safe operator chains 2026-02-06 22:36:57 +01:00
Fabien Potencier eb516c9740 minor #4755 Add a not about the return value of destructuring (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Add a not about the return value of destructuring

Commits
-------

c38868cdd0 Add a not about the return value of destructuring
2026-02-06 22:15:10 +01:00
Fabien Potencier 3cc1b5233c Add support for renaming variables in object destructuring 2026-02-06 22:12:59 +01:00
Fabien Potencier 09e6bb5a91 Bump version 2026-02-06 22:12:49 +01:00
Fabien Potencier c38868cdd0 Add a not about the return value of destructuring 2026-02-04 22:36:00 +01:00
Fabien Potencier 87848155a5 minor #4749 Fix null-safe operator test (HypeMC)
This PR was merged into the 3.x branch.

Discussion
----------

Fix null-safe operator test

Noticed this while working on #4748.

Without `strict_variables`, the tests always pass, even when the null-safe operator is not used.

Commits
-------

a16ac6bd35 Fix null-safe operator test
2026-01-27 11:37:59 +01:00
HypeMC a16ac6bd35 Fix null-safe operator test 2026-01-25 04:57:19 +01:00
Fabien Potencier 111b867703 Bump version 2026-01-23 22:27:43 +01:00
Fabien Potencier a64dc5d2cc Prepare the release v3.23.0 2026-01-23 22:00:41 +01:00
Fabien Potencier b0c42a9739 Update CHANGELOG 2026-01-23 22:00:23 +01:00
Fabien Potencier b609ae9d0d feature #4744 Add support for object and mapping destructuring (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Add support for object and mapping destructuring

Refs https://github.com/twigphp/Twig/issues/3399

Commits
-------

8a0f8acbdf Add support for object and mapping destructuring
2026-01-23 12:57:17 +01:00
William Desportes 79aecfbae0 Update .gitattributes to remove splitsh.json 2026-01-22 09:55:32 +00:00
Fabien Potencier 8a0f8acbdf Add support for object and mapping destructuring 2026-01-21 13:21:14 +01:00
Fabien Potencier 76c404ec67 Rename classes 2026-01-21 13:14:16 +01:00
Fabien Potencier d784400fb2 feature #4742 Assignment operator array destructuring (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Assignment operator array destructuring

Follow-up to the introduction of the new = operator, array destructuring.
Refs #3399

Commits
-------

bb99af3b39 Assignment operator array destructuring
2026-01-21 08:46:31 +01:00
Fabien Potencier bb99af3b39 Assignment operator array destructuring 2026-01-21 08:46:28 +01:00
Fabien Potencier dfeb162464 Fix doc notes 2026-01-21 08:36:53 +01:00
Fabien Potencier 85ccfb10c2 Fix doc notes 2026-01-21 08:34:47 +01:00
Fabien Potencier be1797da0c feature #4735 Add the = assignment operator (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Add the = assignment operator

Commits
-------

bfbbef05f2 Add the = assignment operator
2026-01-19 21:23:20 +01:00
Fabien Potencier bfbbef05f2 Add the = assignment operator 2026-01-19 16:39:57 +01:00
Fabien Potencier 820eed38a1 minor #4741 Fix grammar and spelling mistakes in documentation (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix grammar and spelling mistakes in documentation

Commits
-------

77cd2fd9f7 Fix grammar and spelling mistakes in documentation
2026-01-17 22:38:28 +01:00
Fabien Potencier 77cd2fd9f7 Fix grammar and spelling mistakes in documentation 2026-01-17 22:34:06 +01:00
Fabien Potencier c02aa11d0c minor #4740 Tweak null-safe operator implementation (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Tweak null-safe operator implementation

Follow-up for #4717

Commits
-------

6904954165 Tweak null-safe operator implementation
2026-01-17 15:14:24 +01:00
Fabien Potencier 6904954165 Tweak null-safe operator implementation 2026-01-17 15:11:37 +01:00
Fabien Potencier b1b2a0923f feature #4717 Add null-safe operator (felds)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Add null-safe operator

Adds native support for Twig’s null-safe `?.` operator so templates can traverse objects and arrays without defensive plumbing: `{{ user?.address?.city }}` now renders the value when present and stays silent when any hop is `null`.

`?.` reuses the existing `GetAttrExpression` operator, so it should have otherwise the same precedence and behavior as `.`.

Usage cases can be found in the tests:
https://github.com/twigphp/Twig/blob/7d98d45f58df040f41a81f7f8d4cce6c42be781e/tests/ExpressionParserTest.php#L304-L343

Tests cover both the rendered output and the generated PHP.

Let me know if any tests are missing or if the implementation should be done any other way.

Commits
-------

263c04fd1f Add null-safe operator
2026-01-17 14:57:55 +01:00
Felds Liscia 263c04fd1f Add null-safe operator 2026-01-17 14:57:47 +01:00
Fabien Potencier 2bddfddb7d minor #4737 Update u.rst to clarify truncate method's third argument behavior (Always-Victorious)
This PR was merged into the 3.x branch.

Discussion
----------

Update u.rst to clarify truncate method's third argument behavior

Current wording "to preserve whole words" suggests setting the argument to ``true`` preserves words. However, the parameter is ``$cut`` (defaults to ``true`` for cutting at exact length), and ``false`` is required to preserve whole words.

Commits
-------

28c2606be7 Update u.rst to clarify truncate method's third argument behavior
2026-01-17 10:27:09 +01:00
Fabien Potencier bd4b47e38c minor #4739 Fix documentation for getOperators() (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix documentation for getOperators()

Closes #4710

Commits
-------

ae51f93f70 Fix documentation for getOperators()
2026-01-17 10:21:12 +01:00
Fabien Potencier ae51f93f70 Fix documentation for getOperators() 2026-01-17 10:19:56 +01:00
Fabien Potencier 141e984c3e minor #4738 bump version (xabbuh)
This PR was merged into the 3.x branch.

Discussion
----------

bump version

#4736 added new operators thus require the minor version to be increased

Commits
-------

55cb67f87d bump version
2026-01-16 13:48:36 +01:00
Christian Flothmann 55cb67f87d bump version 2026-01-16 11:26:26 +01:00
Always-Victorious 28c2606be7 Update u.rst to clarify truncate method's third argument behavior
Current wording "to preserve whole words" suggests setting the argument to ``true`` preserves words. However, the parameter is ``$cut`` (defaults to ``true`` for cutting at exact length), and ``false`` is required to preserve whole words.
2026-01-15 15:43:42 +01:00
Fabien Potencier 94abd1c39b feature #4736 Add === and !== operators (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Add === and !== operators

Commits
-------

94c8bdd6a6 Add === and !== operators
2026-01-14 22:27:11 +01:00
Fabien Potencier 3ef425879d minor #4726 Enhance enum.rst with dynamic case example (Kocal)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Enhance enum.rst with dynamic case example

Added example for dynamic enum case display.

Commits
-------

bcc5ffc301 Enhance enum.rst with dynamic case example
2026-01-14 22:26:14 +01:00
Hugo Alliaume bcc5ffc301 Enhance enum.rst with dynamic case example 2026-01-14 22:26:11 +01:00
Fabien Potencier 94c8bdd6a6 Add === and !== operators 2026-01-14 09:58:48 +01:00
Fabien Potencier 0b1ef6cda0 minor #4734 Update extends.rst (MAHADEV-J)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Update extends.rst

Semantically correct HTML elements instead of `<div>`itis

Commits
-------

5b63d90bfb Update extends.rst
2026-01-14 08:47:34 +01:00
MAHADEV-J 5b63d90bfb Update extends.rst 2026-01-14 08:47:31 +01:00