Skip to content

Commit 100a74f

Browse files
committed
Merge pull request symfony#1215 from Inori/cookbook/custom-twig-extension
[Cookbook][Templating] custom Twig Extension
2 parents ae17f1f + 61a5042 commit 100a74f

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

book/templating.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,7 @@ Learn more from the Cookbook
13341334

13351335
* :doc:`/cookbook/templating/PHP`
13361336
* :doc:`/cookbook/controller/error_pages`
1337+
* :doc:`/cookbook/templating/twig_extension`
13371338

13381339
.. _`Twig`: http://twig.sensiolabs.org
13391340
.. _`KnpBundles.com`: http://knpbundles.com

cookbook/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Cookbook
7171

7272
templating/global_variables
7373
templating/PHP
74+
templating/twig_extension
7475

7576
logging/monolog
7677
logging/monolog_email

cookbook/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292

9393
* :doc:`/cookbook/templating/global_variables`
9494
* :doc:`/cookbook/templating/PHP`
95+
* :doc:`/cookbook/templating/twig_extension`
9596

9697
* **Logging**
9798

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
.. index::
2+
single: Twig extensions
3+
4+
How to write a custom Twig Extension
5+
====================================
6+
7+
The main motivation for writing an extension is to move often used code
8+
into a reusable class like adding support for internationalization.
9+
An extension can define tags, filters, tests, operators, global variables,
10+
functions, and node visitors.
11+
12+
Creating an extension also makes for a better separation of code that is
13+
executed at compilation time and code needed at runtime. As such, it makes
14+
your code faster.
15+
16+
.. tip::
17+
18+
Before writing your own extensions, have a look at the `Twig official extension repository`_.
19+
20+
Create the Extension Class
21+
--------------------------
22+
23+
To get your custom functionality you must first create a Twig Extension class.
24+
As an example we will create a price filter to format a given number into price::
25+
26+
// src/Acme/DemoBundle/Twig/AcmeExtension.php
27+
28+
namespace Acme\DemoBundle\Twig;
29+
30+
use Twig_Extension;
31+
use Twig_Filter_Method;
32+
use Twig_Function_Method;
33+
34+
class AcmeExtension extends Twig_Extension
35+
{
36+
public function getFilters()
37+
{
38+
return array(
39+
'price' => new Twig_Filter_Method($this, 'priceFilter'),
40+
);
41+
}
42+
43+
public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
44+
{
45+
$price = number_format($number, $decimals, $decPoint, $thousandsSep);
46+
$price = '$' . $price;
47+
48+
return $price;
49+
}
50+
51+
public function getName()
52+
{
53+
return 'acme_extension';
54+
}
55+
}
56+
57+
.. tip::
58+
59+
Along with custom filters, you can also add custom `functions` and register `global variables`.
60+
61+
Register an Extension as a Service
62+
-------------------------------
63+
64+
Now you must let Service Container know about your newly created Twig Extension:
65+
66+
.. configuration-block::
67+
68+
.. code-block:: xml
69+
70+
<!-- src/Acme/DemoBundle/Resources/config/services.xml -->
71+
<services>
72+
<service id="acme.twig.acme_extension" class="Acme\DemoBundle\Twig\AcmeExtension">
73+
<tag name="twig.extension" />
74+
</service>
75+
</services>
76+
77+
.. code-block:: yaml
78+
79+
# src/Acme/DemoBundle/Resources/config/services.yml
80+
services:
81+
acme.twig.acme_extension:
82+
class: Acme\DemoBundle\Twig\AcmeExtension
83+
tags:
84+
- { name: twig.extension }
85+
86+
.. code-block:: php
87+
88+
// src/Acme/DemoBundle/Resources/config/services.php
89+
use Symfony\Component\DependencyInjection\Definition;
90+
91+
$acmeDefinition = new Definition('\Acme\DemoBundle\Twig\AcmeExtension');
92+
$acmeDefinition->addTag('twig.extension');
93+
$container->setDefinition('acme.twig.acme_extension', $acmeDefinition);
94+
95+
.. note::
96+
97+
Keep in mind that Twig Extensions are not lazily loaded. This means that
98+
there's a higher chance that you'll get a **CircularReferenceException**
99+
or a **ScopeWideningInjectionException** if any services
100+
(or your Twig Extension in this case) are dependent on the request service.
101+
For more information take a look at :doc:`/cookbook/service_container/scopes`.
102+
103+
Using the custom Extension
104+
--------------------------
105+
106+
Using your newly created Twig Extension is no different than any other:
107+
108+
.. code-block:: jinja
109+
110+
{# outputs $5,500.00 #}
111+
{{ '5500' | price }}
112+
113+
Passing other arguments to your filter:
114+
115+
.. code-block:: jinja
116+
117+
{# outputs $5500,2516 #}
118+
{{ '5500.25155' | price(4, ',', '') }}
119+
120+
Learning further
121+
----------------
122+
123+
For a more in-depth look into Twig Extensions, please take a look at the `Twig extensions documentation`_.
124+
125+
.. _`Twig official extension repository`: http://github.com/fabpot/Twig-extensions
126+
.. _`Twig extensions documentation`: http://twig.sensiolabs.org/doc/extensions.html
127+
.. _`global variables`: http://twig.sensiolabs.org/doc/extensions.html#globals
128+
.. _`functions`: http://twig.sensiolabs.org/doc/extensions.html#functions

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy