Commit Graph

7800 Commits

Author SHA1 Message Date
Nicolas Grekas ef3780c2e0 Speed up loading compiled templates that OPcache already holds 2026-09-30 22:20:34 +02:00
Fabien Potencier c471d2ad58 minor #4976 Speed up traversing nodes with node visitors (nicolas-grekas)
This PR was merged into the 3.x branch.

Discussion
----------

Speed up traversing nodes with node visitors

`NodeTraverser` walks the whole tree once per node visitor, and it iterated over the children of each node with `foreach ($node as ...)`, which allocates an `ArrayIterator` per node and per visitor. It now reads the children array through a new internal `Node::getNodes()` method. On the Symfony Demo, where six visitors are registered, walking the 21k nodes of its 52 templates takes half the instructions it took, and warming up its Twig cache runs 15% fewer instructions and takes 520ms instead of 566ms.

The traverser doesn't go through `getIterator()` anymore, so a subclass overriding it to hide children from visitors would be bypassed, and one declaring its own `getNodes()` would clash; I found none in Twig, Symfony or UX. Calling `getArrayCopy()` on the iterator returned by `getIterator()` would avoid the new method, but it saves 13% of the traversal instructions instead of 50%: `new \ArrayIterator()` and `getArrayCopy()` both copy the array.

<details>
<summary>Merge-up notes</summary>

To 4.x: the patch applies as is (I ran the 4.x suite with it), the CHANGELOG entry doesn't go to 4.x.

</details>

Commits
-------

69fefec125 Speed up traversing nodes with node visitors
2026-09-30 22:13:13 +02:00
Nicolas Grekas 69fefec125 Speed up traversing nodes with node visitors 2026-09-30 22:13:07 +02:00
Fabien Potencier e7de480373 feature #4951 Allow skipping the directory check when adding paths to FilesystemLoader (nicolas-grekas)
This PR was merged into the 3.x branch.

Discussion
----------

Allow skipping the directory check when adding paths to `FilesystemLoader`

`FilesystemLoader::addPath()` and `prependPath()` call `is_dir()` on each path, so an app built from a compiled container pays for it on each request, even though the paths were checked when the container was built. This adds a third argument to skip the check:

```php
$loader->addPath($templateDir, 'admin', false);
```

It's read with `func_get_arg()` because Drupal and Contao override both methods with two arguments. On the Symfony Demo, where TwigBundle registers 14 paths, building the loader goes from 64µs to 21µs per request once TwigBundle passes `false` (symfony/symfony#66334).

<details>
<summary>Merge-up notes</summary>

To 4.x: declare the argument for real, `bool $check = true`, instead of reading it with `func_get_arg()`; the tests apply as is. The CHANGELOG and `doc/deprecated.rst` entries don't go to 4.x, and the `versionadded` block has to be removed from `doc/api.rst` since the 4.x docs have none.

</details>

Commits
-------

9e1e2e2cea Allow skipping the directory check when adding paths to `FilesystemLoader`
2026-09-30 21:59:42 +02:00
Nicolas Grekas 9e1e2e2cea Allow skipping the directory check when adding paths to FilesystemLoader 2026-09-30 21:16:25 +02:00
Fabien Potencier c72c875b91 bug #4980 Fix the deprecated tag generating invalid PHP for an integer message (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix the deprecated tag generating invalid PHP for an integer message

Closes #4978

Commits
-------

c6f1ef9521 Fix the deprecated tag generating invalid PHP for an integer message
2026-09-28 12:38:24 +02:00
Fabien Potencier c6f1ef9521 Fix the deprecated tag generating invalid PHP for an integer message 2026-09-28 12:38:11 +02:00
Fabien Potencier d79ac7e60d bug #4974 Fix the loop variable of a for tag being undefined in the sequence of a nested loop (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix the loop variable of a for tag being undefined in the sequence of a nested loop

Commits
-------

0c90971a98 Fix the loop variable of a for tag being undefined in the sequence of a nested loop
2026-09-28 12:26:36 +02:00
Fabien Potencier 3b32fb9231 bug #4979 Reject the spread operator outside sequences, mappings, and call arguments (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Reject the spread operator outside sequences, mappings, and call arguments

Closes #4977

Commits
-------

a04ae6d636 Reject the spread operator outside sequences, mappings, and call arguments
2026-09-28 12:25:34 +02:00
Fabien Potencier a04ae6d636 Reject the spread operator outside sequences, mappings, and call arguments 2026-09-27 19:43:42 +02:00
Fabien Potencier 0c90971a98 Fix the loop variable of a for tag being undefined in the sequence of a nested loop 2026-09-26 10:54:52 +02:00
Fabien Potencier 4241bb73fe bug #4964 Discard what the non-selected branch of a guard tag registers on the parser (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Discard what the non-selected branch of a guard tag registers on the parser

Commits
-------

d5011f4654 Discard what the non-selected branch of a guard tag registers on the parser
2026-09-26 10:43:26 +02:00
Fabien Potencier d5011f4654 Discard what the non-selected branch of a guard tag registers on the parser 2026-09-26 10:43:21 +02:00
Fabien Potencier 14a0e4adb3 bug #4960 Reset the escaping state when compiling a new template after a compilation error (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Reset the escaping state when compiling a new template after a compilation error

Commits
-------

39642e4cdf Reset the escaping state when compiling a new template after a compilation error
2026-09-26 10:41:59 +02:00
Fabien Potencier 39642e4cdf Reset the escaping state when compiling a new template after a compilation error 2026-09-26 10:41:54 +02:00
Fabien Potencier 6ec06d1883 bug #4959 Reject a Template instance created by another environment when resolving templates (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Reject a Template instance created by another environment when resolving templates

Commits
-------

605b1278f7 Reject a Template instance created by another environment when resolving templates
2026-09-26 10:38:49 +02:00
Fabien Potencier 550ac879b3 documentation #4958 3.x doc fixes (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

3.x doc fixes

Commits
-------

1478f9efcd Fix the class name and a missing parenthesis in the runtime loader example
e883536e64 Replace the deprecated twig_test_even function in the custom test example
db3aeb7379 Use the current variable node class in the node tree example
2026-09-26 10:36:51 +02:00
Fabien Potencier 452419d64a documentation #4962 Fix the autoescape documentation about static expressions (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix the autoescape documentation about static expressions

Commits
-------

95a176f2bf Fix the autoescape documentation about static expressions
2026-09-26 10:36:25 +02:00
Fabien Potencier c7c9f62b0f bug #4972 Fix the sandbox not reporting the line of a rejected guard tag (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fix the sandbox not reporting the line of a rejected guard tag

Commits
-------

b1d6b51183 Fix the sandbox not reporting the line of a rejected guard tag
2026-09-26 10:35:30 +02:00
Fabien Potencier acab707eb2 documentation #4973 Use sandbox policy examples that remain meaningful in Twig 4.0 (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Use sandbox policy examples that remain meaningful in Twig 4.0

Commits
-------

677f049e64 Use sandbox policy examples that remain meaningful in Twig 4.0
2026-09-26 10:32:18 +02:00
Fabien Potencier 677f049e64 Use sandbox policy examples that remain meaningful in Twig 4.0 2026-09-26 10:30:06 +02:00
Fabien Potencier e0af798ea9 minor #4965 Rewrite the sandbox documentation around what developers need to know (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Rewrite the sandbox documentation around what developers need to know

Commits
-------

9d24327f8d Rewrite the sandbox documentation around what developers need to know
2026-09-26 10:23:05 +02:00
Fabien Potencier b1d6b51183 Fix the sandbox not reporting the line of a rejected guard tag 2026-09-26 10:22:21 +02:00
Fabien Potencier 9d24327f8d Rewrite the sandbox documentation around what developers need to know 2026-09-26 10:02:08 +02:00
Fabien Potencier 1478f9efcd Fix the class name and a missing parenthesis in the runtime loader example 2026-09-25 23:53:05 +02:00
Fabien Potencier e883536e64 Replace the deprecated twig_test_even function in the custom test example 2026-09-25 23:53:05 +02:00
Fabien Potencier db3aeb7379 Use the current variable node class in the node tree example 2026-09-25 23:53:00 +02:00
Fabien Potencier 95a176f2bf Fix the autoescape documentation about static expressions 2026-09-25 23:45:00 +02:00
Fabien Potencier 605b1278f7 Reject a Template instance created by another environment when resolving templates 2026-09-25 23:34:59 +02:00
Fabien Potencier 2904612341 minor #4949 Skip the property checker call and memoize the class constant probe when reading an object attribute (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Skip the property checker call and memoize the class constant probe when reading an object attribute

Commits
-------

ddd9045b5c Skip the property checker call and memoize the class constant probe when reading an object attribute
2026-09-25 16:01:04 +02:00
Fabien Potencier ddd9045b5c Skip the property checker call and memoize the class constant probe when reading an object attribute 2026-09-25 16:00:51 +02:00
Fabien Potencier cbcfe403a0 bug #4947 Stop looking up a macro twice in its own namespace when it is declared by a parent (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Stop looking up a macro twice in its own namespace when it is declared by a parent

Commits
-------

e3f0d6fb4c Stop looking up a macro twice in its own namespace when it is declared by a parent
2026-09-25 15:50:23 +02:00
Fabien Potencier 2558df70b6 Bump version 2026-09-25 15:20:29 +02:00
Fabien Potencier 8c737079b7 Prepare the 3.30.0 release v3.30.0 2026-09-25 15:20:01 +02:00
Fabien Potencier 052c7efdde minor #4950 Fetch the escaper runtime once in the constructor of templates that escape (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Fetch the escaper runtime once in the constructor of templates that escape

Commits
-------

3417f483bf Fetch the escaper runtime once in the constructor of templates that escape
2026-09-25 12:45:04 +02:00
Fabien Potencier 3417f483bf Fetch the escaper runtime once in the constructor of templates that escape 2026-09-25 12:44:56 +02:00
Fabien Potencier 9e198d7637 minor #4948 Compare the date formatter prototype pattern with the derived one once per pattern (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Compare the date formatter prototype pattern with the derived one once per pattern

Commits
-------

10fe9808bb Compare the date formatter prototype pattern with the derived one once per pattern
2026-09-25 12:41:20 +02:00
Fabien Potencier 22e31198e7 bug #4946 Fix split trailing newline (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Fix split trailing newline

Commits
-------

00861d50ab Fix split trailing newline
2026-09-25 12:39:42 +02:00
Fabien Potencier 00861d50ab Fix split trailing newline 2026-09-25 12:39:38 +02:00
Fabien Potencier 81cc196cae Bump version 2026-09-25 07:50:37 +02:00
Fabien Potencier e3f0d6fb4c Stop looking up a macro twice in its own namespace when it is declared by a parent 2026-09-25 07:50:11 +02:00
Fabien Potencier 10fe9808bb Compare the date formatter prototype pattern with the derived one once per pattern 2026-09-25 07:50:11 +02:00
Fabien Potencier c8d782ea0b Deprecate calling TemplateWrapper::unwrap() without arguments as of 3.30 and list the fix in the CHANGELOG 2026-09-25 07:44:32 +02:00
Fabien Potencier 9c3d58e638 Fix coding standards 2026-09-25 07:44:12 +02:00
Fabien Potencier 4d073d938a Drop a comment restating the code and clarify the fully named macro call fast path 2026-09-25 07:44:00 +02:00
Fabien Potencier 9d33a10324 minor #4945 Speed up adding extensions to an environment (nicolas-grekas)
This PR was merged into the 3.x branch.

Discussion
----------

Speed up adding extensions to an environment

`Environment::addExtension()` recomputes the options hash on every call, JSON-encoding the class names of all the extensions registered so far. This computes it only when a template class name is needed. With the 24 extensions TwigBundle registers on the Symfony Demo, building the environment drops from 87µs to 19µs, and calling `setExtensions()` once instead brings nothing more.

Merge-up to 4.x: the property is typed there, so it has to become `private ?string $optionsHash = null;` (I ran the 4.x suite with that change). The CHANGELOG entry doesn't go to 4.x.

Commits
-------

d3d13f9b1a Speed up adding extensions to an environment
2026-09-24 19:20:19 +02:00
Nicolas Grekas d3d13f9b1a Speed up adding extensions to an environment 2026-09-24 18:47:14 +02:00
Fabien Potencier efa368c8d7 minor #4940 Reuse the already resolved callable when compiling call arguments (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Reuse the already resolved callable when compiling call arguments

Commits
-------

16be8af8f5 Reuse the already resolved callable when compiling call arguments
2026-09-23 07:18:00 +01:00
Fabien Potencier 16be8af8f5 Reuse the already resolved callable when compiling call arguments 2026-09-23 07:17:53 +01:00
Fabien Potencier 154ae335bb minor #4939 Compile the generator guard as an unreachable yield instead of a yield from (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Compile the generator guard as an unreachable yield instead of a yield from

Commits
-------

4d5d233776 Compile the generator guard as an unreachable yield instead of a yield from
2026-09-23 07:16:36 +01:00