How to Write a custom Twig Extension
Warning: You are browsing the documentation for Symfony 2.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.1 (the current stable version).
The main motivation for writing an extension is to move often used code into a reusable class like adding support for internationalization. An extension can define tags, filters, tests, operators, global variables, functions, and node visitors.
Creating an extension also makes for a better separation of code that is executed at compilation time and code needed at runtime. As such, it makes your code faster.
Tip
Before writing your own extensions, have a look at the Twig official extension repository.
Create the Extension Class
Note
This article describes how to write a custom Twig extension as of Twig 1.12. If you are using an older version, please read Twig extensions documentation legacy.
To get your custom functionality you must first create a Twig Extension class. As an example you'll create a price filter to format a given number into price:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// src/AppBundle/Twig/AppExtension.php
namespace AppBundle\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class AppExtension extends AbstractExtension
{
public function getFilters()
{
return array(
new TwigFilter('price', array($this, 'formatPrice')),
);
}
public function formatPrice($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
{
$price = number_format($number, $decimals, $decPoint, $thousandsSep);
$price = '$'.$price;
return $price;
}
}
Note
Prior to Twig 1.26, your extension had to define an additional getName()
method that returned a string with the extension's internal name (e.g.
app.my_extension
). When your extension needs to be compatible with Twig
versions before 1.26, include this method which is omitted in the example
above.
Here's how to create a custom function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/AppBundle/Twig/AppExtension.php
namespace AppBundle\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class AppExtension extends AbstractExtension
{
public function getFunctions()
{
return array(
new TwigFunction('area', array($this, 'calculateArea')),
);
}
public function calculateArea(int $width, int $length)
{
return $width * $length;
}
}
Tip
Along with custom filters and functions, you can also register global variables.
Register an Extension as a Service
Now you must let the Service Container know about your newly created Twig Extension:
1 2 3 4 5 6 7
# app/config/services.yml
services:
app.twig_extension:
class: AppBundle\Twig\AppExtension
public: false
tags:
- { name: twig.extension }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.twig_extension"
class="AppBundle\Twig\AppExtension"
public="false">
<tag name="twig.extension" />
</service>
</services>
</container>
1 2 3 4 5 6 7
// app/config/services.php
use AppBundle\Twig\AppExtension;
$container
->register('app.twig_extension', AppExtension::class)
->setPublic(false)
->addTag('twig.extension');
Using the custom Extension
Using your newly created Twig Extension is no different than any other:
1 2 3 4 5 6 7 8
{# Using the filter without arguments. Outputs $5,500.00 #}
{{ '5500'|price }}
{# Passing arguments to the filter. Outputs $5500,2516 #}
{{ '5500.25155'|price(4, ',', '') }}
{# Passing arguments to the function. Outputs 140 #}
Total area: {{ area(20, 7) }}
Learning further
For a more in-depth look into Twig Extensions, please take a look at the Twig extensions documentation.