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_iterable
function is deprecated; use the native PHPis_iterable
function instead. The
attribute
function 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\EscaperExtension
are deprecated:setEscaper()
,getEscapers()
,setSafeClasses
,addSafeClasses()
. Use the same methods on theTwig\Runtime\EscaperRuntime
class instead:Before:
$twig->getExtension(EscaperExtension::class)->METHOD();
After:
$twig->getRuntime(EscaperRuntime::class)->METHOD();
Nodes
- The "tag" constructor parameter of the
Twig\Node\Node
class is deprecated as of Twig 3.12 as the tag is now automatically set by the Parser when needed. - Passing a second argument to "ExpressionParser::parseFilterExpressionRaw()" is deprecated as of Twig 3.12.
- The following
Twig\Node\Node
methods 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
BodyNode
instance as the body of aModuleNode
orMacroNode
constructor is deprecated as of Twig 3.12. - Returning
null
fromTokenParserInterface::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
filter
node ofTwig\Node\Expression\FilterExpression
is deprecated as of Twig 3.12 and will be removed in 4.0. Use thefilter
attribute 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\TestExpression
is deprecated as of Twig 3.12. As of Twig 4.0, you need to pass aTwigFunction
,TwigFilter
, orTestFilter
instead.Let's take a
FunctionExpression
as an example.If you have a node that extends
FunctionExpression
and 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\FirstClassTwigCallableReady
attribute.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\FunctionExpression
attributes are deprecated as of Twig 3.12:needs_charset
,needs_environment
,needs_context
,arguments
,callable
,is_variadic
, anddynamic_name
. - The following
Twig\Node\Expression\FilterExpression
attributes are deprecated as of Twig 3.12:needs_charset
,needs_environment
,needs_context
,arguments
,callable
,is_variadic
, anddynamic_name
. - The following
Twig\Node\Expression\TestExpression
attributes are deprecated as of Twig 3.12:arguments
,callable
,is_variadic
, anddynamic_name
. - The
MethodCallExpression
class is deprecated as of Twig 3.15, useMacroReferenceExpression
instead. - The
Twig\Node\Expression\TempNameExpression
class is deprecated as of Twig 3.15; useTwig
instead.\Node \Expression \Variable \LocalVariable - The
Twig\Node\Expression\NameExpression
class is deprecated as of Twig 3.15; useTwig
instead.\Node \Expression \Variable \ContextVariable - The
Twig\Node\Expression\AssignNameExpression
class is deprecated as of Twig 3.15; useTwig
instead.\Node \Expression \Variable \AssignContextVariable - Node implementations that use
echo
orprint
should useyield
instead; all Node implementations should use the#[\Twig\Attribute\YieldReady]
attribute on their class once they've been made ready foryield
; theuse_yield
Environment option can be turned on when all nodes use the#[\Twig\Attribute\YieldReady]
attribute.
- The
Twig\Node\InlinePrint
class is deprecated as of Twig 3.16 with no replacement.- The
Twig\Node\Expression\NullCoalesceExpression
class is deprecated as of Twig 3.17, useTwig
instead.\Node \Expression \Binary \NullCoalesceBinary - The
Twig\Node\Expression\ConditionalExpression
class is deprecated as of Twig 3.17, useTwig
instead.\Node \Expression \Ternary \ConditionalTernary
Node Visitors
- The
Twig\NodeVisitor\AbstractNodeVisitor
class is deprecated, implement theTwig\NodeVisitor\NodeVisitorInterface
interface instead. - The
Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER
and theTwig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES
options 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\Parser
are deprecated as of Twig 3.12:getBlockStack()
,hasBlock()
,getBlock()
,hasMacro()
,hasTraits()
,getParent()
. - The
Twig\ExpressionParser::parseHashExpression()
method is deprecated, useTwig\ExpressionParser::parseMappingExpression()
instead. - The
Twig\ExpressionParser::parseArrayExpression()
method is deprecated, useTwig\ExpressionParser::parseSequenceExpression()
instead. - Passing
null
toTwig\Parser::setParent()
is deprecated as of Twig 3.12.
Lexer
- Not passing a
Source
instance toTwig\TokenStream
constructor is deprecated as of Twig 3.16.
Templates
- Passing
Twig\Template
instances to Twig public API is deprecated (like inEnvironment::resolveTemplate()
,Environment::load()
, andTemplate::loadTemplate()
); pass instances ofTwig\TemplateWrapper
instead.
Filters
- The
spaceless
filter is deprecated as of Twig 3.12 and will be removed in Twig 4.0.
Sandbox
- Having the
extends
anduse
tags 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
sandbox
tag, use thesandboxed
option of theinclude
function 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\NodeTestCase
have 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\IntegrationTestCase
is deprecated, implement the new static methodgetFixturesDirectory()
instead, which will be abstract in 4.0. - The data providers
getTests()
andgetLegacyTests()
onTwig\Test\IntegrationTestCase
are 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
,alternative
options on Twig functions/filters/Tests are deprecated as of Twig 3.15, and will be removed in Twig 4.0. Use thedeprecation_info
option 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
string
or anarray
to Twig callable arguments accepting arrow functions is deprecated as of Twig 3.15; these arguments will have a\Closure
type hint in 4.0. - Returning
null
fromTwigFilter::getSafe()
andTwigFunction::getSafe()
is deprecated as of Twig 3.16; return[]
instead.
Node
- Instantiating
Twig\Node\Node
directly is deprecated as of Twig 3.15. UseEmptyNode
orNodes
instead depending on the use case. TheTwig\Node\Node
class will be abstract in Twig 4.0. Not passing
AbstractExpression
arguments to the followingNode
class constructors is deprecated as of Twig 3.15:AbstractBinary
AbstractUnary
BlockReferenceExpression
TestExpression
DefinedTest
FilterExpression
RawFilter
DefaultFilter
InlinePrint
NullCoalesceExpression
Operators
- 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
not
unary 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,not
will 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 #}