@@ -58,14 +58,121 @@ Create a class that extends ``\Twig_Extension`` and fill in the logic::
5858 `global variables `_.
5959
6060Register an Extension as a Service
61- ----------------------------------
61+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6262
6363Next, register your class as a service and tag it with ``twig.extension ``. If you're
6464using the :ref: `default services.yml configuration <service-container-services-load-example >`,
6565you're done! Symfony will automatically know about your new service and add the tag.
6666
6767You 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