Commit Graph

7764 Commits

Author SHA1 Message Date
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 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
Fabien Potencier 4d5d233776 Compile the generator guard as an unreachable yield instead of a yield from 2026-09-22 22:00:07 +01:00
Fabien Potencier c33dd1c473 feature #4938 Speed up loading a template that the environment has already loaded (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Speed up loading a template that the environment has already loaded

`Environment::load()` allocated a fresh `TemplateWrapper` on every call, even when the template was already loaded. Since `TemplateWrapper` is immutable, the same instance can be reused.

**Performance** (PHP 8.5, interleaved A/B, min of 5 runs):

| Workload | Before | After | |
|---|---:|---:|---:|
| Repeated `load()` of a loaded template | ~800 ns | ~610 ns | **−24%** |
| Page render: layout + 41 `include()` calls | 133 µs | 127 µs | **−5%** |

Commits
-------

6f94a47ce1 Reuse the template wrapper of an already loaded template
2026-09-22 21:03:17 +01:00
Fabien Potencier 6f94a47ce1 Reuse the template wrapper of an already loaded template 2026-09-22 21:02:38 +01:00
Fabien Potencier ff4a1c6575 bug #4937 Stop the escaping safe analysis from retaining every analyzed node (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Stop the escaping safe analysis from retaining every analyzed node

Commits
-------

8274571d04 Stop the escaping safe analysis from retaining every analyzed node
2026-09-22 20:42:55 +01:00
Fabien Potencier 8274571d04 Stop the escaping safe analysis from retaining every analyzed node 2026-09-22 16:47:34 +01:00
Fabien Potencier a890011699 feature #4936 Allow to call TemplateWrapper::unwrap() without arguments (derrabus)
This PR was merged into the 3.x branch.

Discussion
----------

Allow to call `TemplateWrapper::unwrap()` without arguments

Fixes #4935, symfony/symfony#66193.

#4910 changed an internal API that has famously been used by Symfony since almost forever. We would now need to change Symfony's 5.4 branch which is security-only. Because of that, I'd like to propose to allow calling `TemplateWrapper::unwrap()` without parameters again. This should allow running Symfony 5.4 with the latest Twig 3 again.

We can revert my change on the 4.x branch.

Commits
-------

bfbe89e3a3 Allow to call TemplateWrapper::unwrap() without arguments
2026-09-22 11:27:53 +01:00
Alexander M. Turek bfbe89e3a3 Allow to call TemplateWrapper::unwrap() without arguments 2026-09-22 09:22:57 +02:00
Fabien Potencier 4b7c937485 feature #4934 Expose the escaping strategy a template was compiled with (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Expose the escaping strategy a template was compiled with

Compiled templates now record the escaping strategy they were compiled with and expose it via `TemplateWrapper::getDefaultEscapeStrategy()`, so the strategy of a template can be known without deriving it again from its name, which is both slower and can disagree with how its content was actually escaped.

Commits
-------

26812ebc0d Expose the escaping strategy a template was compiled with
2026-09-21 11:30:14 +01:00
Fabien Potencier 26812ebc0d Expose the escaping strategy a template was compiled with 2026-09-21 11:30:11 +01:00
Fabien Potencier ea3258396c minor #4933 Improve macro call performance (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Improve macro call performance

This is mostly about getting back to the same performance we had in 3.28.

Commits
-------

a8ee6dd762 Improve macro call performance
2026-09-20 21:28:10 +01:00
Fabien Potencier a8ee6dd762 Improve macro call performance 2026-09-20 21:28:03 +01:00
Fabien Potencier 66406ea727 bug #4932 Fix IntlExtension inheriting values derived by ICU from a date formatter prototype (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Fix IntlExtension inheriting values derived by ICU from a date formatter prototype

Commits
-------

6671288259 Fix IntlExtension inheriting values derived by ICU from a date formatter prototype
2026-09-20 20:33:34 +01:00
Fabien Potencier 6671288259 Fix IntlExtension inheriting values derived by ICU from a date formatter prototype 2026-09-20 20:33:31 +01:00
Fabien Potencier d722e8af93 bug #4931 Fix array access with a Stringable key on subclasses of ArrayObject and ArrayIterator (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Fix array access with a Stringable key on subclasses of ArrayObject and ArrayIterator

Commits
-------

4aae99e92c Fix array access with a Stringable key on subclasses of ArrayObject and ArrayIterator
2026-09-20 20:17:49 +01:00
Fabien Potencier 4aae99e92c Fix array access with a Stringable key on subclasses of ArrayObject and ArrayIterator 2026-09-20 20:17:42 +01:00
Fabien Potencier 33437bc409 Ignore the PHPUnit 10+ cache directory 2026-09-18 18:50:53 +01:00
Fabien Potencier 0037a49ac4 bug #4930 Report a clear error when a string cannot be split into characters (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Report a clear error when a string cannot be split into characters

Commits
-------

1ee9dae55a Cover and document the matches operator throwing on an invalid UTF-8 subject
5c1be030c5 Report a clear error when a string cannot be split into characters
2026-09-18 17:49:12 +01:00
Fabien Potencier 1ee9dae55a Cover and document the matches operator throwing on an invalid UTF-8 subject 2026-09-18 17:15:53 +01:00
Fabien Potencier 5c1be030c5 Report a clear error when a string cannot be split into characters 2026-09-18 17:15:50 +01:00
Fabien Potencier 8eb76e2b7e feature #4929 Deprecate cloning a Twig environment (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Deprecate cloning a Twig environment

Commits
-------

55afb2e084 Deprecate cloning a Twig environment
2026-09-18 16:54:00 +01:00
Fabien Potencier 55afb2e084 Deprecate cloning a Twig environment 2026-09-18 16:52:58 +01:00
Fabien Potencier 5b3a60a31b minor #4928 Report the macro call parentheses deprecation once per call site and name the macro (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Report the macro call parentheses deprecation once per call site and name the macro

Commits
-------

40d57c6445 Report the macro call parentheses deprecation once per call site and name the macro
2026-09-18 16:51:15 +01:00
Fabien Potencier 40d57c6445 Report the macro call parentheses deprecation once per call site and name the macro 2026-09-18 12:17:08 +02:00
Fabien Potencier b1fe79b610 Bump version 2026-09-18 11:10:56 +02:00
Fabien Potencier 45a3c6e922 Prepare the 3.29.0 release v3.29.0 2026-09-18 11:10:14 +02:00
Fabien Potencier 15207e0090 Update CHANGELOG 2026-09-18 11:10:01 +02:00
Fabien Potencier dea0483027 feature #4910 Reject template wrappers from another environment (fabpot)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Reject template wrappers from another environment

Twig now rejects `TemplateWrapper` instances created by another `Environment`.

This prevents templates from unexpectedly using another environment's loader, extensions, globals, or sandbox policy.

Commits
-------

83e8f7e123 Reject cross-environment template wrappers in block chains
c1fc112047 Reject cross-environment template wrappers
2026-09-14 14:11:48 +02:00
Fabien Potencier 0f5c902d85 bug #4927 Report a clear error when using macros imported in a template body that was not rendered (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Report a clear error when using macros imported in a template body that was not rendered

Commits
-------

72c2f669bd Report a clear error when using macros imported in a template body that was not rendered
2026-09-14 14:05:45 +02:00
Fabien Potencier 56e5c0794b Clarify the exception message for nested block chains from another environment 2026-09-14 11:59:20 +02:00
Fabien Potencier 053200bc89 feature #4926 Allow block chains to be composed of other block chains (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Allow block chains to be composed of other block chains

This is something that is needed by Symfony (and other OSS projects), so better to have it directly in Twig.

Commits
-------

d6b81f9074 Allow block chains to be composed of other block chains
2026-09-14 11:26:36 +02:00
Fabien Potencier d6b81f9074 Allow block chains to be composed of other block chains 2026-09-14 11:17:44 +02:00
Fabien Potencier 72c2f669bd Report a clear error when using macros imported in a template body that was not rendered 2026-09-12 12:17:17 +02:00
Fabien Potencier 83e8f7e123 Reject cross-environment template wrappers in block chains 2026-09-12 09:57:01 +02:00
Fabien Potencier c1fc112047 Reject cross-environment template wrappers 2026-09-12 09:51:36 +02:00
Fabien Potencier a414c3a491 feature #4925 Resolve block chains against the render context (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Resolve block chains against the render context

While working on the Symfony PR for #4917, I realize that the performance was worse with the Twig's way. #4924 fixes part of the performance "regression". This one closes the gap.

`BlockChain` currently freezes each template's lineage by cloning it, so the block map and `parent()` both resolve `{% extends %}` against the constructor context.

This PR changes that to resolve the chain against the render context instead. `hasBlock()` and `getBlockNames()` take a context, like `TemplateWrapper` already does, and the third constructor argument becomes a default the render context can override. A lineage whose templates all have a fixed parent (none, or constant) is resolved once and cached, so the common case costs nothing; a dynamic `{% extends %}` re-resolves per call (not use by Symfony anyway).

This fixes also an inconsistency: a chained template with a dynamic parent now behaves exactly as it does when rendered directly. It also removes all changes in the "core" logic of Template.

```
                       construct    render   1 chain + 40 renders
Symfony's engine today   13.44us    0.78us         50.3us
#4917                    ~70us      0.96us        ~117us
this PR                   0.61us    0.84us         53.0us
```

Commits
-------

897717d78f Resolve block chains against the render context instead of freezing lineages
2026-09-12 09:49:05 +02:00
Fabien Potencier 897717d78f Resolve block chains against the render context instead of freezing lineages 2026-09-12 00:03:19 +02:00