Deprecated Features
This document lists deprecated features in Twig 3.x. Deprecated features are kept for backward compatibility and removed in the next major release (a feature that was deprecated in Twig 3.x is removed in Twig 4.0).
Functions
- The
twig_test_iterablefunction is deprecated; use the native PHPis_iterablefunction instead. The
attributefunction is deprecated as of Twig 3.15. Use the.operator instead and wrap the name with parenthesis:1 2 3 4 5 6 7 8 9
{# before #} {{ attribute(object, method) }} {{ attribute(object, method, arguments) }} {{ attribute(array, item) }} {# after #} {{ object.(method) }} {{ object.(method)(arguments) }} {{ array[item] }}Note that it won't be removed in 4.0 to allow a smoother upgrade path.
Extensions
All functions defined in Twig extensions are marked as internal as of Twig 3.9.0, and will be removed in Twig 4.0. They have been replaced by internal methods on their respective extension classes.
If you were using the
twig_escape_filter()function in your code, use$env->getRuntime(EscaperRuntime::class)->escape()instead.The following methods from
Twig\Extension\EscaperExtensionare deprecated:setEscaper(),getEscapers(),setSafeClasses,addSafeClasses(). Use the same methods on theTwig\Runtime\EscaperRuntimeclass instead:Before:
$twig->getExtension(EscaperExtension::class)->METHOD();After:
$twig->getRuntime(EscaperRuntime::class)->METHOD();
Nodes
- The "tag" constructor parameter of the
Twig\Node\Nodeclass is deprecated as of Twig 3.12 as the tag is now automatically set by the Parser when needed. - The following
Twig\Node\Nodemethods will take a string or an integer (instead of just a string) in Twig 4.0 for their "name" argument:getNode(),hasNode(),setNode(),removeNode(), anddeprecateNode(). - Not passing a
BodyNodeinstance as the body of aModuleNodeorMacroNodeconstructor is deprecated as of Twig 3.12. - Returning
nullfromTokenParserInterface::parse()is deprecated as of Twig 3.12 (as forbidden by the interface). - The second argument of the
Twig\Node\Expression\CallExpression::compileArguments()method is deprecated. - The
Twig\Node\Expression\NameExpression::isSimple()andTwig\Node\Expression\NameExpression::isSpecial()methods are deprecated as
of Twig 3.11 and will be removed in Twig 4.0. The
filternode ofTwig\Node\Expression\FilterExpressionis deprecated as of Twig 3.12 and will be removed in 4.0. Use thefilterattribute instead to get the filter:Before:
$node->getNode('filter')->getAttribute('value')After:
$node->getAttribute('twig_callable')->getName()Passing a name to
Twig\Node\Expression\FunctionExpression,Twig\Node\Expression\FilterExpression, andTwig\Node\Expression\TestExpressionis deprecated as of Twig 3.12. As of Twig 4.0, you need to pass aTwigFunction,TwigFilter, orTestFilterinstead.Let's take a
FunctionExpressionas an example.If you have a node that extends
FunctionExpressionand if you don't override the constructor, you don't need to do anything. But if you override the constructor, then you need to change the type hint of the name and mark the constructor with theTwig\Attribute\FirstClassTwigCallableReadyattribute.Before:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
class NotReadyFunctionExpression extends FunctionExpression { public function __construct(string $function, Node $arguments, int $lineno) { parent::__construct($function, $arguments, $lineno); } } class NotReadyFilterExpression extends FilterExpression { public function __construct(Node $node, ConstantExpression $filter, Node $arguments, int $lineno) { parent::__construct($node, $filter, $arguments, $lineno); } } class NotReadyTestExpression extends TestExpression { public function __construct(Node $node, string $test, ?Node $arguments, int $lineno) { parent::__construct($node, $test, $arguments, $lineno); } }After:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
class ReadyFunctionExpression extends FunctionExpression { #[FirstClassTwigCallableReady] public function __construct(TwigFunction|string $function, Node $arguments, int $lineno) { parent::__construct($function, $arguments, $lineno); } } class ReadyFilterExpression extends FilterExpression { #[FirstClassTwigCallableReady] public function __construct(Node $node, TwigFilter|ConstantExpression $filter, Node $arguments, int $lineno) { parent::__construct($node, $filter, $arguments, $lineno); } } class ReadyTestExpression extends TestExpression { #[FirstClassTwigCallableReady] public function __construct(Node $node, TwigTest|string $test, ?Node $arguments, int $lineno) { parent::__construct($node, $test, $arguments, $lineno); } }- The following
Twig\Node\Expression\FunctionExpressionattributes are deprecated as of Twig 3.12:needs_charset,needs_environment,needs_context,arguments,callable,is_variadic, anddynamic_name. - The following
Twig\Node\Expression\FilterExpressionattributes are deprecated as of Twig 3.12:needs_charset,needs_environment,needs_context,arguments,callable,is_variadic, anddynamic_name. - The following
Twig\Node\Expression\TestExpressionattributes are deprecated as of Twig 3.12:arguments,callable,is_variadic, anddynamic_name. - The
MethodCallExpressionclass is deprecated as of Twig 3.15, useMacroReferenceExpressioninstead. - The
Twig\Node\Expression\TempNameExpressionclass is deprecated as of Twig 3.15; useTwiginstead.\Node \Expression \Variable \LocalVariable - The
Twig\Node\Expression\NameExpressionclass is deprecated as of Twig 3.15; useTwiginstead.\Node \Expression \Variable \ContextVariable - The
Twig\Node\Expression\AssignNameExpressionclass is deprecated as of Twig 3.15; useTwiginstead.\Node \Expression \Variable \AssignContextVariable - Node implementations that use
echoorprintshould useyieldinstead; all Node implementations should use the#[\Twig\Attribute\YieldReady]attribute on their class once they've been made ready foryield; theuse_yieldEnvironment option can be turned on when all nodes use the#[\Twig\Attribute\YieldReady]attribute.
- The
Twig\Node\InlinePrintclass is deprecated as of Twig 3.16 with no replacement.- The
Twig\Node\Expression\NullCoalesceExpressionclass is deprecated as of Twig 3.17, useTwiginstead.\Node \Expression \Binary \NullCoalesceBinary - The
Twig\Node\Expression\ConditionalExpressionclass is deprecated as of Twig 3.17, useTwiginstead.\Node \Expression \Ternary \ConditionalTernary - The
is_defined_testattribute is deprecated as of Twig 3.21, useTwig\Node\Expression\SupportDefinedTestInterfaceinstead.
- Instantiating
Twig\Node\Nodedirectly is deprecated as of Twig 3.15. UseEmptyNodeorNodesinstead depending on the use case. TheTwig\Node\Nodeclass will be abstract in Twig 4.0. Not passing
AbstractExpressionarguments to the followingNodeclass constructors is deprecated as of Twig 3.15:AbstractBinaryAbstractUnaryBlockReferenceExpressionTestExpressionDefinedTestFilterExpressionRawFilterDefaultFilterInlinePrintNullCoalesceExpression
Node Visitors
- The
Twig\NodeVisitor\AbstractNodeVisitorclass is deprecated, implement theTwig\NodeVisitor\NodeVisitorInterfaceinterface instead. - The
Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTERand theTwig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_TEXT_NODESoptions are deprecated as of Twig 3.12 and will be removed in Twig 4.0; they don't do anything anymore.
Parser
- The following methods from
Twig\Parserare deprecated as of Twig 3.12:getBlockStack(),hasBlock(),getBlock(),hasMacro(),hasTraits(),getParent(). - Passing
nulltoTwig\Parser::setParent()is deprecated as of Twig 3.12. - The
Twig\Parser::getExpressionParser()method is deprecated as of Twig 3.21, useTwig\Parser::parseExpression()instead. The
Twig\ExpressionParserclass is deprecated as of Twig 3.21:parseExpression(), useParser::parseExpression()parsePrimaryExpression(), useParser::parseExpression()parseStringExpression(), useParser::parseExpression()parseHashExpression(), useParser::parseExpression()parseMappingExpression(), useParser::parseExpression()parseArrayExpression(), useParser::parseExpression()parseSequenceExpression(), useParser::parseExpression()parsePostfixExpressionparseSubscriptExpressionparseFilterExpressionparseFilterExpressionRawparseArguments(), useTwig\ExpressionParser\Infix\ArgumentsTrait::parseNamedArguments()parseAssignmentExpression, useAbstractTokenParser::parseAssignmentExpressionparseMultitargetExpressionparseOnlyArguments(), useTwig\ExpressionParser\Infix\ArgumentsTrait::parseNamedArguments()
Token
- Not passing a
Sourceinstance toTwig\TokenStreamconstructor is deprecated as of Twig 3.16. - The
Token::getType()method is deprecated as of Twig 3.19, useToken::test()instead. - The
Token::ARROW_TYPEconstant is deprecated as of Twig 3.21, the arrow=>is now an operator (Token::OPERATOR_TYPE). - The
Token::PUNCTUATION_TYPEwith values(,[,|,.,?, or?:are now of theToken::OPERATOR_TYPEtype.
Templates
- The method
Template::loadTemplate()is deprecated. - Passing
Twig\Templateinstances to Twig public API is deprecated (like inEnvironment::resolveTemplate()andEnvironment::load()); pass instances ofTwig\TemplateWrapperinstead.
Filters
- The
spacelessfilter is deprecated as of Twig 3.12 and will be removed in Twig 4.0.
Sandbox
- Having the
extendsandusetags allowed by default in a sandbox is deprecated as of Twig 3.12. You will need to explicitly allow them if needed in 4.0. Deprecate the
sandboxtag, use thesandboxedoption of theincludefunction instead:Before:
1 2 3
{% sandbox %} {% include 'user_defined.html.twig' %} {% endsandbox %}After:
1
{{ include('user_defined.html.twig', sandboxed: true) }}
Testing Utilities
- Implementing the data provider method
Twig\Test\NodeTestCase::getTests()is deprecated as of Twig 3.13. Instead, implement the static data providerprovideTests(). - In order to make their functionality available for static data providers, the
helper methods
getVariableGetter()andgetAttributeGetter()onTwig\Test\NodeTestCasehave been deprecated. Call the new methodscreateVariableGetter()andcreateAttributeGetter()instead. - The method
Twig\Test\NodeTestCase::getEnvironment()is considered final as of Twig 3.13. If you want to override how the Twig environment is constructed, overridecreateEnvironment()instead. - The method
getFixturesDir()onTwig\Test\IntegrationTestCaseis deprecated, implement the new static methodgetFixturesDirectory()instead, which will be abstract in 4.0. - The data providers
getTests()andgetLegacyTests()onTwig\Test\IntegrationTestCaseare considered final as of Twig 3.13.
Environment
The
Twig\Environment::mergeGlobals()method is deprecated as of Twig 3.14 and will be removed in Twig 4.0:Before:
1
$context = $twig->mergeGlobals($context);After:
1
$context += $twig->getGlobals();
Functions/Filters/Tests
The
deprecated,deprecating_package,alternativeoptions on Twig functions/filters/Tests are deprecated as of Twig 3.15, and will be removed in Twig 4.0. Use thedeprecation_infooption instead:Before:
1 2 3
$twig->addFunction(new TwigFunction('upper', 'upper', [ 'deprecated' => '3.12', 'deprecating_package' => 'twig/twig', ]));After:
1 2 3
$twig->addFunction(new TwigFunction('upper', 'upper', [ 'deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.12'), ]));- For variadic arguments, use snake-case for the argument name to ease the transition to 4.0.
- Passing a
stringor anarrayto Twig callable arguments accepting arrow functions is deprecated as of Twig 3.15; these arguments will have a\Closuretype hint in 4.0. - Returning
nullfromTwigFilter::getSafe()andTwigFunction::getSafe()is deprecated as of Twig 3.16; return[]instead.
Operators
- An operator precedence must be part of the [0, 512] range as of Twig 3.21.
- The
.operator allows accessing class constants as of Twig 3.15. This can be a BC break if you don't use UPPERCASE constant names. Using
~in an expression with the+or-operators without using parentheses to clarify precedence triggers a deprecation as of Twig 3.15 (in Twig 4.0,+/-will have a higher precedence than~).For example, the following expression will trigger a deprecation in Twig 3.15:
1
{{ '42' ~ 1 + 41 }}To avoid the deprecation, wrap the concatenation in parentheses to clarify the precedence:
1 2 3 4 5
{{ ('42' ~ 1) + 41 }} {# this is equivalent to what Twig 3.x does without the parentheses #} {# or #} {{ '42' ~ (1 + 41) }} {# this is equivalent to what Twig 4.x will do without the parentheses #}Using
??without explicit parentheses to clarify precedence triggers a deprecation as of Twig 3.15 (in Twig 4.0,??will have the lowest precedence).For example, the following expression will trigger a deprecation in Twig 3.15:
1
{{ 'notnull' ?? 'foo' ~ '_bar' }}To avoid the deprecation, wrap the
??expression in parentheses to clarify the precedence:1 2 3 4 5
{{ ('notnull' ?? 'foo') ~ '_bar' }} {# this is equivalent to what Twig 3.x does without the parentheses #} {# or #} {{ 'notnull' ?? ('foo' ~ '_bar') }} {# this is equivalent to what Twig 4.x will do without the parentheses #}Using the
notunary operator in an expression with*,/,//, or%operators without explicit parentheses to clarify precedence triggers a deprecation as of Twig 3.15 (in Twig 4.0,notwill have a higher precedence than*,/,//, and%).For example, the following expression will trigger a deprecation in Twig 3.15:
1
{{ not 1 * 2 }}To avoid the deprecation, wrap the concatenation in parentheses to clarify the precedence:
1 2 3 4 5
{{ (not 1 * 2) }} {# this is equivalent to what Twig 3.x does without the parentheses #} {# or #} {{ (not 1) * 2 }} {# this is equivalent to what Twig 4.x will do without the parentheses #}Using the
|operator in an expression with+or-without explicit parentheses to clarify precedence triggers a deprecation as of Twig 3.21 (in Twig 4.0,|will have a higher precedence than+and-).For example, the following expression will trigger a deprecation in Twig 3.21:
1
{{ -1|abs }}To avoid the deprecation, add parentheses to clarify the precedence:
1 2 3 4 5
{{ -(1|abs) }} {# this is equivalent to what Twig 3.x does without the parentheses #} {# or #} {{ (-1)|abs }} {# this is equivalent to what Twig 4.x will do without the parentheses #}The
Twig\Extension\ExtensionInterface::getOperators()method is deprecated as of Twig 3.21, useTwig\Extension\ExtensionInterface::getExpressionParsers()instead:Before:
1 2 3 4 5 6 7 8
public function getOperators(): array { return [ 'not' => [ 'precedence' => 10, 'class' => NotUnary::class, ], ]; }After:
1 2 3 4 5
public function getExpressionParsers(): array { return [ new UnaryOperatorExpressionParser(NotUnary::class, 'not', 10), ]; }- The
Twig\OperatorPrecedenceChangeclass is deprecated as of Twig 3.21, useTwig\ExpressionParser\PrecedenceChangeinstead.