# 3.19.0 (2025-XX-XX) * Deprecate `Token::getType()`, use `Token::test()` instead * Add `Token::toEnglish()` * Add `ForElseNode` * Deprecate `Twig\ExpressionParser::parseOnlyArguments()` and `Twig\ExpressionParser::parseArguments()` (use `Twig\ExpressionParser::parseNamedArguments()` instead) * Fix `constant()` behavior when used with `??` * Add the `invoke` filter * Make `{}` optional for the `types` tag * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes * Ignore static properties when using the dot operator # 3.18.0 (2024-12-29) * Fix unary operator precedence change * Ignore `SyntaxError` exceptions from undefined handlers when using the `guard` tag * Add a way to stream template rendering (`TemplateWrapper::stream()` and `TemplateWrapper::streamBlock()`) # 3.17.1 (2024-12-12) * Fix the null coalescing operator when the test returns null * Fix the Elvis operator when used as '? :' instead of '?:' * Support for invoking closures # 3.17.0 (2024-12-10) * Fix ArrayAccess with objects as keys * Support underscores in number literals * Deprecate `ConditionalExpression` and `NullCoalesceExpression` (use `ConditionalTernary` and `NullCoalesceBinary` instead) # 3.16.0 (2024-11-29) * Deprecate `InlinePrint` * Fix having macro variables starting with an underscore * Deprecate not passing a `Source` instance to `TokenStream` * Deprecate returning `null` from `TwigFilter::getSafe()` and `TwigFunction::getSafe()`, return `[]` instead # 3.15.0 (2024-11-17) * [BC BREAK] Add support for accessing class constants with the dot operator; this can be a BC break if you don't use UPPERCASE constant names * Add Spanish inflector support for the `plural` and `singular` filters in the String extension * Deprecate `TempNameExpression` in favor of `LocalVariable` * Deprecate `NameExpression` in favor of `ContextVariable` * Deprecate `AssignNameExpression` in favor of `AssignContextVariable` * Remove `MacroAutoImportNodeVisitor` * Deprecate `MethodCallExpression` in favor of `MacroReferenceExpression` * Fix support for the "is defined" test on `_self.xxx` (auto-imported) macros * Fix support for the "is defined" test on inherited macros * Add named arguments support for the dot operator arguments (`foo.bar(some: arg)`) * Add named arguments support for macros * Add a new `guard` tag that allows to test if some Twig callables are available at compilation time * Allow arrow functions everywhere * Deprecate passing a string or an array to Twig callable arguments accepting arrow functions (pass a `\Closure`) * Add support for triggering deprecations for future operator precedence changes * Deprecate using the `not` unary operator in an expression with ``*``, ``/``, ``//``, or ``%`` without using explicit parentheses to clarify precedence * Deprecate using the `??` binary operator without explicit parentheses * Deprecate using the `~` binary operator in an expression with `+` or `-` without using parentheses to clarify precedence * Deprecate not passing `AbstractExpression` args to most constructor arguments for classes extending `AbstractExpression` * Fix `power` expressions with a negative number in parenthesis (`(-1) ** 2`) * Deprecate instantiating `Node` directly. Use `EmptyNode` or `Nodes` instead. * Add support for inline comments * Add `Profile::getStartTime()` and `Profile::getEndTime()` * Fix "ignore missing" when used on an "embed" tag * Fix the possibility to override an aliased block (via use) * Add template cache hot reload * Allow Twig callable argument names to be free-form (snake-case or camelCase) independently of the PHP callable signature They were automatically converted to snake-cased before * Deprecate the `attribute` function; use the `.` notation and wrap the name with parenthesis instead * Add support for argument unpackaging * Add JSON support for the file extension escaping strategy * Support Markup instances (and any other \Stringable) as dynamic mapping keys * Deprecate the `sandbox` tag * Improve the way one can deprecate a Twig callable (use `deprecation_info` instead of the other callable options) * Add the `enum` function * Add support for logical `xor` operator # 3.14.2 (2024-11-07) * Fix an infinite recursion in the sandbox code # 3.14.1 (2024-11-06) * [BC BREAK] Fix a security issue in the sandbox mode allowing an attacker to call attributes on Array-like objects They are now checked via the property policy * Fix a security issue in the sandbox mode allowing an attacker to be able to call `toString()` under some circumstances on an object even if the `__toString()` method is not allowed by the security policy # 3.14.0 (2024-09-09) * Fix a security issue when an included sandboxed template has been loaded before without the sandbox context * Add the possibility to reset globals via `Environment::resetGlobals()` * Deprecate `Environment::mergeGlobals()` # 3.13.0 (2024-09-07) * Add the `types` tag (experimental) * Deprecate the `Twig\Test\NodeTestCase::getTests()` data provider, override `provideTests()` instead. * Mark `Twig\Test\NodeTestCase::getEnvironment()` as final, override `createEnvironment()` instead. * Deprecate `Twig\Test\NodeTestCase::getVariableGetter()`, call `createVariableGetter()` instead. * Deprecate `Twig\Test\NodeTestCase::getAttributeGetter()`, call `createAttributeGetter()` instead. * Deprecate not overriding `Twig\Test\IntegrationTestCase::getFixturesDirectory()`, this method will be abstract in 4.0 * Marked `Twig\Test\IntegrationTestCase::getTests()` and `getLegacyTests()` as final # 3.12.0 (2024-08-29) * Deprecate the fact that the `extends` and `use` tags are always allowed in a sandboxed template. This behavior will change in 4.0 where these tags will need to be explicitly allowed like any other tag. * Deprecate the "tag" constructor argument of the "Twig\Node\Node" class as the tag is now automatically set by the Parser when needed * Fix precedence of two-word tests when the first word is a valid test * Deprecate the `spaceless` filter * Deprecate some internal methods from `Parser`: `getBlockStack()`, `hasBlock()`, `getBlock()`, `hasMacro()`, `hasTraits()`, `getParent()` * Deprecate passing `null` to `Twig\Parser::setParent()` * Update `Node::__toString()` to include the node tag if set * Add support for integers in methods of `Twig\Node\Node` that take a Node name * Deprecate not passing a `BodyNode` instance as the body of a `ModuleNode` or `MacroNode` constructor * Deprecate returning "null" from "TokenParserInterface::parse()". * Deprecate `OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES` * Fix performance regression when `use_yield` is `false` (which is the default) * Improve compatibility when `use_yield` is `false` (as extensions still using `echo` will work as is) * Accept colons (`:`) in addition to equals (`=`) to separate argument names and values in named arguments * Add the `html_cva` function (in the HTML extra package) * Add support for named arguments to the `block` and `attribute` functions * Throw a SyntaxError exception at compile time when a Twig callable has not the minimum number of required arguments * Add a `CallableArgumentsExtractor` class * Deprecate passing a name to `FunctionExpression`, `FilterExpression`, and `TestExpression`; pass a `TwigFunction`, `TwigFilter`, or `TestFilter` instead * Deprecate all Twig callable attributes on `FunctionExpression`, `FilterExpression`, and `TestExpression` * Deprecate the `filter` node of `FilterExpression` * Add the notion of Twig callables (functions, filters, and tests) * Bump minimum PHP version to 8.0 * Fix integration tests when a test has more than one data/expect section and deprecations * Add the `enum_cases` function # 3.11.2 (2024-11-06) * [BC BREAK] Fix a security issue in the sandbox mode allowing an attacker to call attributes on Array-like objects They are now checked via the property policy * Fix a security issue in the sandbox mode allowing an attacker to be able to call `toString()` under some circumstances on an object even if the `__toString()` method is not allowed by the security policy # 3.11.1 (2024-09-10) * Fix a security issue when an included sandboxed template has been loaded before without the sandbox context # 3.11.0 (2024-08-08) * Deprecate `OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER` * Add `Twig\Cache\ChainCache` and `Twig\Cache\ReadOnlyFilesystemCache` * Add the possibility to deprecate attributes and nodes on `Node` * Add the possibility to add a package and a version to the `deprecated` tag * Add the possibility to add a package for filter/function/test deprecations * Mark `ConstantExpression` as being `@final` * Add the `find` filter * Fix optimizer mode validation in `OptimizerNodeVisitor` * Add the possibility to yield from a generator in `PrintNode` * Add the `shuffle` filter * Add the `singular` and `plural` filters in `StringExtension` * Deprecate the second argument of `Twig\Node\Expression\CallExpression::compileArguments()` * Deprecate `Twig\ExpressionParser\parseHashExpression()` in favor of `Twig\ExpressionParser::parseMappingExpression()` * Deprecate `Twig\ExpressionParser\parseArrayExpression()` in favor of `Twig\ExpressionParser::parseSequenceExpression()` * Add `sequence` and `mapping` tests * Deprecate `Twig\Node\Expression\NameExpression::isSimple()` and `Twig\Node\Expression\NameExpression::isSpecial()` # 3.10.3 (2024-05-16) * Fix missing ; in generated code # 3.10.2 (2024-05-14) * Fix support for the deprecated escaper signature # 3.10.1 (2024-05-12) * Fix BC break on escaper extension * Fix constant return type # 3.10.0 (2024-05-11) * Make `CoreExtension::formatDate`, `CoreExtension::convertDate`, and `CoreExtension::formatNumber` part of the public API * Add `needs_charset` option for filters and functions * Extract the escaping logic from the `EscaperExtension` class to a new `EscaperRuntime` class. The following methods from ``Twig\\Extension\\EscaperExtension`` are deprecated: ``setEscaper()``, ``getEscapers()``, ``setSafeClasses``, ``addSafeClasses()``. Use the same methods on the ``Twig\\Runtime\\EscaperRuntime`` class instead. * Fix capturing output from extensions that still use echo * Fix a PHP warning in the Lexer on malformed templates * Fix blocks not available under some circumstances * Synchronize source context in templates when setting a Node on a Node # 3.9.3 (2024-04-18) * Add missing `twig_escape_filter_is_safe` deprecated function * Fix yield usage with CaptureNode * Add missing unwrap call when using a TemplateWrapper instance internally * Ensure Lexer is initialized early on # 3.9.2 (2024-04-17) * Fix usage of display_end hook # 3.9.1 (2024-04-17) * Fix missing `$blocks` variable in `CaptureNode` # 3.9.0 (2024-04-16) * Add support for PHP 8.4 * Deprecate AbstractNodeVisitor * Deprecate passing Template to Environment::resolveTemplate(), Environment::load(), and Template::loadTemplate() * Add a new "yield" mode for output generation; Node implementations that use "echo" or "print" should use "yield" instead; all Node implementations should be flagged with `#[YieldReady]` once they've been made ready for "yield"; the "use_yield" Environment option can be turned on when all nodes have been made `#[YieldReady]`; "yield" will be the only strategy supported in the next major version * Add return type for Symfony 7 compatibility * Fix premature loop exit in Security Policy lookup of allowed methods/properties * Deprecate all internal extension functions in favor of methods on the extension classes * Mark all extension functions as @internal * Add SourcePolicyInterface to selectively enable the Sandbox based on a template's Source * Throw a proper Twig exception when using cycle on an empty array # 3.8.0 (2023-11-21) * Catch errors thrown during template rendering * Fix IntlExtension::formatDateTime use of date formatter prototype * Fix premature loop exit in Security Policy lookup of allowed methods/properties * Remove NumberFormatter::TYPE_CURRENCY (deprecated in PHP 8.3) * Restore return type annotations * Allow Symfony 7 packages to be installed * Deprecate `twig_test_iterable` function. Use the native `is_iterable` instead. # 3.7.1 (2023-08-28) * Fix some phpdocs # 3.7.0 (2023-07-26) * Add support for the ...spread operator on arrays and hashes # 3.6.1 (2023-06-08) * Suppress some native return type deprecation messages # 3.6.0 (2023-05-03) * Allow psr/container 2.0 * Add the new PHP 8.0 IntlDateFormatter::RELATIVE_* constants for date formatting * Make the Lexer initialize itself lazily # 3.5.1 (2023-02-08) * Arrow functions passed to the "reduce" filter now accept the current key as a third argument * Restores the leniency of the matches twig comparison * Fix error messages in sandboxed mode for "has some" and "has every" # 3.5.0 (2022-12-27) * Make Twig\ExpressionParser non-internal * Add "has some" and "has every" operators * Add Compile::reset() * Throw a better runtime error when the "matches" regexp is not valid * Add "twig *_names" intl functions * Fix optimizing closures callbacks * Add a better exception when getting an undefined constant via `constant` * Fix `if` nodes when outside of a block and with an empty body # 3.4.3 (2022-09-28) * Fix a security issue on filesystem loader (possibility to load a template outside a configured directory) # 3.4.2 (2022-08-12) * Allow inherited magic method to still run with calling class * Fix CallExpression::reflectCallable() throwing TypeError * Fix typo in naming (currency_code) # 3.4.1 (2022-05-17) * Fix optimizing non-public named closures # 3.4.0 (2022-05-22) * Add support for named closures # 3.3.10 (2022-04-06) * Enable bytecode invalidation when auto_reload is enabled # 3.3.9 (2022-03-25) * Fix custom escapers when using multiple Twig environments * Add support for "constant('class', object)" * Do not reuse internally generated variable names during parsing # 3.3.8 (2022-02-04) * Fix a security issue when in a sandbox: the `sort` filter must require a Closure for the `arrow` parameter * Fix deprecation notice on `round` * Fix call to deprecated `convertToHtml` method # 3.3.7 (2022-01-03) * Allow more null support when Twig expects a string (for better 8.1 support) * Only use Commonmark extensions if markdown enabled # 3.3.6 (2022-01-03) * Only use Commonmark extensions if markdown enabled # 3.3.5 (2022-01-03) * Allow CommonMark extensions to easily be added * Allow null when Twig expects a string (for better 8.1 support) * Make some performance optimizations * Allow Symfony translation contract v3+ # 3.3.4 (2021-11-25) * Bump minimum supported Symfony component versions * Fix a deprecated message # 3.3.3 (2021-09-17) * Allow Symfony 6 * Improve compatibility with PHP 8.1 * Explicitly specify the encoding for mb_ord in JS escaper # 3.3.2 (2021-05-16) * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)" # 3.3.1 (2021-05-12) * Fix PHP 8.1 compatibility * Throw a proper exception when a template name is an absolute path (as it has never been supported) # 3.3.0 (2021-02-08) * Fix macro calls in a "cache" tag * Add the slug filter * Allow extra bundle to be compatible with Twig 2 # 3.2.1 (2021-01-05) * Fix extra bundle compat with older versions of Symfony # 3.2.0 (2021-01-05) * Add the Cache extension in the "extra" repositories: "cache" tag * Add "registerUndefinedTokenParserCallback" * Mark built-in node visitors as @internal * Fix "odd" not working for negative numbers # 3.1.1 (2020-10-27) * Fix "include(template_from_string())" # 3.1.0 (2020-10-21) * Fix sandbox support when using "include(template_from_string())" * Make round brackets optional for one argument tests like "same as" or "divisible by" * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } # 3.0.5 (2020-08-05) * Fix twig_compare w.r.t. whitespace trimming * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag * Fix a regression when not using a space before an operator * Restrict callables to closures in filters * Allow trailing commas in argument lists (in calls as well as definitions) # 3.0.4 (2020-07-05) * Fix comparison operators * Fix options not taken into account when using "Michelf\MarkdownExtra" * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument * Throw exception in case non-Traversable data is passed to "filter" * Fix context optimization on PHP 7.4 * Fix PHP 8 compatibility * Fix ambiguous syntax parsing # 3.0.3 (2020-02-11) * Add a check to ensure that iconv() is defined # 3.0.2 (2020-02-11) * Avoid exceptions when an intl resource is not found * Fix implementation of case-insensitivity for method names # 3.0.1 (2019-12-28) * fixed Symfony 5.0 support for the HTML extra extension # 3.0.0 (2019-11-15) * fixed number formatter in Intl extra extension when using a formatter prototype # 3.0.0-BETA1 (2019-11-11) * removed the "if" condition support on the "for" tag * made the in, <, >, <=, >=, ==, and != operators more strict when comparing strings and integers/floats * removed the "filter" tag * added type hints everywhere * changed Environment::resolveTemplate() to always return a TemplateWrapper instance * removed Template::__toString() * removed Parser::isReservedMacroName() * removed SanboxedPrintNode * removed Node::setTemplateName() * made classes marked as "@final" final * removed InitRuntimeInterface, ExistsLoaderInterface, and SourceContextLoaderInterface * removed the "spaceless" tag * removed Twig\Environment::getBaseTemplateClass() and Twig\Environment::setBaseTemplateClass() * removed the "base_template_class" option on Twig\Environment * bumped minimum PHP version to 7.2 * removed PSR-0 classes