Skip to content

Commit a36d58f

Browse files
committed
minor #9204 Documented how to create lazy-loaded Twig extensions (javiereguiluz)
This PR was squashed before being merged into the 3.4 branch (closes #9204). Discussion ---------- Documented how to create lazy-loaded Twig extensions This fixes #7169. Commits ------- 3173fea Documented how to create lazy-loaded Twig extensions
2 parents e03d15b + 3173fea commit a36d58f

File tree

1 file changed

+108
-1
lines changed

1 file changed

+108
-1
lines changed

templating/twig_extension.rst

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,121 @@ Create a class that extends ``\Twig_Extension`` and fill in the logic::
5858
`global variables`_.
5959

6060
Register an Extension as a Service
61-
----------------------------------
61+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6262

6363
Next, register your class as a service and tag it with ``twig.extension``. If you're
6464
using the :ref:`default services.yml configuration <service-container-services-load-example>`,
6565
you're done! Symfony will automatically know about your new service and add the tag.
6666

6767
You can now start using your filter in any Twig template.
6868

69+
Creating Lazy-Loaded Twig Extensions
70+
------------------------------------
71+
72+
.. versionadded:: 1.26
73+
Support for lazy-loaded extensions was introduced in Twig 1.26.
74+
75+
Including the code of the custom filters/functions in the Twig extension class
76+
is the simplest way to create extensions. However, Twig must initialize all
77+
extensions before rendering any template, even if the template doesn't use an
78+
extension.
79+
80+
If extensions don't define dependencies (i.e. if you don't inject services in
81+
them) performance is not affected. However, if extensions define lots of complex
82+
dependencies (e.g. those making database connections), the performance loss can
83+
be significant.
84+
85+
That's why Twig allows to decouple the extension definition from its
86+
implementation. Following the same example as before, the first change would be
87+
to remove the ``priceFilter()`` method from the extension and update the PHP
88+
callable defined in ``getFilters()``::
89+
90+
// src/AppBundle/Twig/AppExtension.php
91+
namespace AppBundle\Twig;
92+
93+
use AppBundle\Twig\AppRuntime;
94+
95+
class AppExtension extends \Twig_Extension
96+
{
97+
public function getFilters()
98+
{
99+
return array(
100+
// the logic of this filter is now implemented in a different class
101+
new \Twig_SimpleFilter('price', array(AppRuntime::class, 'priceFilter')),
102+
);
103+
}
104+
}
105+
106+
Then, create the new ``AppRuntime`` class (it's not required but these classes
107+
are suffixed with ``Runtime`` by convention) and include the logic of the
108+
previous ``priceFilter()`` method::
109+
110+
// src/AppBundle/Twig/AppRuntime.php
111+
namespace AppBundle\Twig;
112+
113+
class AppRuntime
114+
{
115+
public function __construct()
116+
{
117+
// this simple example doesn't define any dependency, but in your own
118+
// extensions, you'll need to inject services using this constructor
119+
}
120+
121+
public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
122+
{
123+
$price = number_format($number, $decimals, $decPoint, $thousandsSep);
124+
$price = '$'.$price;
125+
126+
return $price;
127+
}
128+
}
129+
130+
Register the Lazy-Loaded Extension as a Service
131+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132+
133+
Finally, register your new class as a service and tag it with ``twig.runtime``
134+
(and optionally inject any service needed by the Twig extension runtime):
135+
136+
.. configuration-block::
137+
138+
.. code-block:: yaml
139+
140+
# app/config/services.yml
141+
services:
142+
app.twig_runtime:
143+
class: AppBundle\Twig\AppRuntime
144+
public: false
145+
tags:
146+
- { name: twig.runtime }
147+
148+
.. code-block:: xml
149+
150+
<!-- app/config/services.xml -->
151+
<?xml version="1.0" encoding="UTF-8" ?>
152+
<container xmlns="http://symfony.com/schema/dic/services"
153+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
154+
xsi:schemaLocation="http://symfony.com/schema/dic/services
155+
http://symfony.com/schema/dic/services/services-1.0.xsd">
156+
157+
<services>
158+
<service id="app.twig_runtime"
159+
class="AppBundle\Twig\AppRuntime"
160+
public="false">
161+
<tag name="twig.runtime" />
162+
</service>
163+
</services>
164+
</container>
165+
166+
.. code-block:: php
167+
168+
// app/config/services.php
169+
use AppBundle\Twig\AppExtension;
170+
171+
$container
172+
->register('app.twig_runtime', AppRuntime::class)
173+
->setPublic(false)
174+
->addTag('twig.runtime');
175+
69176
.. _`Twig extensions documentation`: http://twig.sensiolabs.org/doc/advanced.html#creating-an-extension
70177
.. _`global variables`: http://twig.sensiolabs.org/doc/advanced.html#id1
71178
.. _`functions`: http://twig.sensiolabs.org/doc/advanced.html#id2

0 commit comments

Comments
 (0)