@@ -1553,23 +1553,20 @@ as currency:
1553
1553
{# pass in the 3 optional arguments #}
1554
1554
{{ product.price|price(2, ',', '.') }}
1555
1555
1556
- Create a class that extends ``AbstractExtension `` and fill in the logic::
1556
+ .. _templates-twig-filter-attribute :
1557
+
1558
+ Create a class with a method that contains the filter logic, then add
1559
+ the ``#[AsTwigFilter] `` attribute to define the name and options of
1560
+ the Twig filter::
1557
1561
1558
1562
// src/Twig/AppExtension.php
1559
1563
namespace App\Twig;
1560
1564
1561
- use Twig\Extension\AbstractExtension;
1562
- use Twig\TwigFilter;
1565
+ use Twig\Attribute\AsTwigFilter;
1563
1566
1564
- class AppExtension extends AbstractExtension
1567
+ class AppExtension
1565
1568
{
1566
- public function getFilters(): array
1567
- {
1568
- return [
1569
- new TwigFilter('price', [$this, 'formatPrice']),
1570
- ];
1571
- }
1572
-
1569
+ #[AsTwigFilter('price')]
1573
1570
public function formatPrice(float $number, int $decimals = 0, string $decPoint = '.', string $thousandsSep = ','): string
1574
1571
{
1575
1572
$price = number_format($number, $decimals, $decPoint, $thousandsSep);
@@ -1579,24 +1576,19 @@ Create a class that extends ``AbstractExtension`` and fill in the logic::
1579
1576
}
1580
1577
}
1581
1578
1582
- If you want to create a function instead of a filter, define the
1583
- ``getFunctions() `` method::
1579
+ .. _templates-twig-function-attribute :
1580
+
1581
+ If you want to create a function instead of a filter, use the
1582
+ ``#[AsTwigFunction] `` attribute::
1584
1583
1585
1584
// src/Twig/AppExtension.php
1586
1585
namespace App\Twig;
1587
1586
1588
- use Twig\Extension\AbstractExtension;
1589
- use Twig\TwigFunction;
1587
+ use Twig\Attribute\AsTwigFunction;
1590
1588
1591
- class AppExtension extends AbstractExtension
1589
+ class AppExtension
1592
1590
{
1593
- public function getFunctions(): array
1594
- {
1595
- return [
1596
- new TwigFunction('area', [$this, 'calculateArea']),
1597
- ];
1598
- }
1599
-
1591
+ #[AsTwigFunction('area')]
1600
1592
public function calculateArea(int $width, int $length): int
1601
1593
{
1602
1594
return $width * $length;
@@ -1608,6 +1600,16 @@ If you want to create a function instead of a filter, define the
1608
1600
Along with custom filters and functions, you can also register
1609
1601
`global variables `_.
1610
1602
1603
+ .. versionadded :: 7.3
1604
+
1605
+ Support for the ``#[AsTwigFilter] ``, ``#[AsTwigFunction] `` and ``#[AsTwigTest] `` attributes was introduced in Symfony 7.3.
1606
+ Previously, you had to extend the ``AbstractExtension `` class, and override the
1607
+ ``getFilters() `` and ``getFunctions() `` methods.
1608
+
1609
+ When using autoconfiguration, the tag ``twig.attribute_extension `` is added automatically
1610
+ when a Twig attribute is used on a method of a class. Otherwise, when autoconfiguration is not enabled,
1611
+ it needs to be added in the service definition.
1612
+
1611
1613
Register an Extension as a Service
1612
1614
..................................
1613
1615
@@ -1631,10 +1633,10 @@ this command to confirm that your new filter was successfully registered:
1631
1633
Creating Lazy-Loaded Twig Extensions
1632
1634
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1633
1635
1634
- Including the code of the custom filters/functions in the Twig extension class
1635
- is the simplest way to create extensions. However, Twig must initialize all
1636
- extensions before rendering any template, even if the template doesn't use an
1637
- extension.
1636
+ When using attributes to extend Twig, the services are initialized only when
1637
+ the functions or filters are used to render the template. But in case you use the
1638
+ classic approach by extending the `` AbstractExtension `` class, Twig initializes all the extensions before
1639
+ rendering any template, even if the extension is not used in the template .
1638
1640
1639
1641
If extensions don't define dependencies (i.e. if you don't inject services in
1640
1642
them) performance is not affected. However, if extensions define lots of complex
0 commit comments