]>
Commit | Line | Data |
---|---|---|
4f5b44bd NL |
1 | Twig for Developers |
2 | =================== | |
3 | ||
4 | This chapter describes the API to Twig and not the template language. It will | |
5 | be most useful as reference to those implementing the template interface to | |
6 | the application and not those who are creating Twig templates. | |
7 | ||
8 | Basics | |
9 | ------ | |
10 | ||
11 | Twig uses a central object called the **environment** (of class | |
12 | ``Twig_Environment``). Instances of this class are used to store the | |
13 | configuration and extensions, and are used to load templates from the file | |
14 | system or other locations. | |
15 | ||
16 | Most applications will create one ``Twig_Environment`` object on application | |
17 | initialization and use that to load templates. In some cases it's however | |
18 | useful to have multiple environments side by side, if different configurations | |
19 | are in use. | |
20 | ||
21 | The simplest way to configure Twig to load templates for your application | |
22 | looks roughly like this:: | |
23 | ||
24 | require_once '/path/to/lib/Twig/Autoloader.php'; | |
25 | Twig_Autoloader::register(); | |
26 | ||
27 | $loader = new Twig_Loader_Filesystem('/path/to/templates'); | |
28 | $twig = new Twig_Environment($loader, array( | |
29 | 'cache' => '/path/to/compilation_cache', | |
30 | )); | |
31 | ||
32 | This will create a template environment with the default settings and a loader | |
33 | that looks up the templates in the ``/path/to/templates/`` folder. Different | |
34 | loaders are available and you can also write your own if you want to load | |
35 | templates from a database or other resources. | |
36 | ||
37 | .. note:: | |
38 | ||
39 | Notice that the second argument of the environment is an array of options. | |
40 | The ``cache`` option is a compilation cache directory, where Twig caches | |
41 | the compiled templates to avoid the parsing phase for sub-sequent | |
42 | requests. It is very different from the cache you might want to add for | |
43 | the evaluated templates. For such a need, you can use any available PHP | |
44 | cache library. | |
45 | ||
46 | To load a template from this environment you just have to call the | |
47 | ``loadTemplate()`` method which then returns a ``Twig_Template`` instance:: | |
48 | ||
49 | $template = $twig->loadTemplate('index.html'); | |
50 | ||
51 | To render the template with some variables, call the ``render()`` method:: | |
52 | ||
53 | echo $template->render(array('the' => 'variables', 'go' => 'here')); | |
54 | ||
55 | .. note:: | |
56 | ||
57 | The ``display()`` method is a shortcut to output the template directly. | |
58 | ||
59 | You can also load and render the template in one fell swoop:: | |
60 | ||
61 | echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here')); | |
62 | ||
63 | .. _environment_options: | |
64 | ||
65 | Environment Options | |
66 | ------------------- | |
67 | ||
68 | When creating a new ``Twig_Environment`` instance, you can pass an array of | |
69 | options as the constructor second argument:: | |
70 | ||
71 | $twig = new Twig_Environment($loader, array('debug' => true)); | |
72 | ||
73 | The following options are available: | |
74 | ||
75 | * ``debug``: When set to ``true``, the generated templates have a | |
76 | ``__toString()`` method that you can use to display the generated nodes | |
77 | (default to ``false``). | |
78 | ||
79 | * ``charset``: The charset used by the templates (default to ``utf-8``). | |
80 | ||
81 | * ``base_template_class``: The base template class to use for generated | |
82 | templates (default to ``Twig_Template``). | |
83 | ||
84 | * ``cache``: An absolute path where to store the compiled templates, or | |
85 | ``false`` to disable caching (which is the default). | |
86 | ||
87 | * ``auto_reload``: When developing with Twig, it's useful to recompile the | |
88 | template whenever the source code changes. If you don't provide a value for | |
89 | the ``auto_reload`` option, it will be determined automatically based on the | |
90 | ``debug`` value. | |
91 | ||
92 | * ``strict_variables``: If set to ``false``, Twig will silently ignore invalid | |
93 | variables (variables and or attributes/methods that do not exist) and | |
94 | replace them with a ``null`` value. When set to ``true``, Twig throws an | |
95 | exception instead (default to ``false``). | |
96 | ||
97 | * ``autoescape``: If set to ``true``, auto-escaping will be enabled by default | |
98 | for all templates (default to ``true``). As of Twig 1.8, you can set the | |
99 | escaping strategy to use (``html``, ``js``, ``false`` to disable). | |
100 | As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``, | |
101 | ``html_attr``, or a PHP callback that takes the template "filename" and must | |
102 | return the escaping strategy to use -- the callback cannot be a function name | |
103 | to avoid collision with built-in escaping strategies). | |
104 | ||
105 | * ``optimizations``: A flag that indicates which optimizations to apply | |
106 | (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to | |
107 | disable). | |
108 | ||
109 | Loaders | |
110 | ------- | |
111 | ||
112 | Loaders are responsible for loading templates from a resource such as the file | |
113 | system. | |
114 | ||
115 | Compilation Cache | |
116 | ~~~~~~~~~~~~~~~~~ | |
117 | ||
118 | All template loaders can cache the compiled templates on the filesystem for | |
119 | future reuse. It speeds up Twig a lot as templates are only compiled once; and | |
120 | the performance boost is even larger if you use a PHP accelerator such as APC. | |
121 | See the ``cache`` and ``auto_reload`` options of ``Twig_Environment`` above | |
122 | for more information. | |
123 | ||
124 | Built-in Loaders | |
125 | ~~~~~~~~~~~~~~~~ | |
126 | ||
127 | Here is a list of the built-in loaders Twig provides: | |
128 | ||
129 | ``Twig_Loader_Filesystem`` | |
130 | .......................... | |
131 | ||
132 | .. versionadded:: 1.10 | |
133 | The ``prependPath()`` and support for namespaces were added in Twig 1.10. | |
134 | ||
135 | ``Twig_Loader_Filesystem`` loads templates from the file system. This loader | |
136 | can find templates in folders on the file system and is the preferred way to | |
137 | load them:: | |
138 | ||
139 | $loader = new Twig_Loader_Filesystem($templateDir); | |
140 | ||
141 | It can also look for templates in an array of directories:: | |
142 | ||
143 | $loader = new Twig_Loader_Filesystem(array($templateDir1, $templateDir2)); | |
144 | ||
145 | With such a configuration, Twig will first look for templates in | |
146 | ``$templateDir1`` and if they do not exist, it will fallback to look for them | |
147 | in the ``$templateDir2``. | |
148 | ||
149 | You can add or prepend paths via the ``addPath()`` and ``prependPath()`` | |
150 | methods:: | |
151 | ||
152 | $loader->addPath($templateDir3); | |
153 | $loader->prependPath($templateDir4); | |
154 | ||
155 | The filesystem loader also supports namespaced templates. This allows to group | |
156 | your templates under different namespaces which have their own template paths. | |
157 | ||
158 | When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods, | |
159 | specify the namespace as the second argument (when not specified, these | |
160 | methods act on the "main" namespace):: | |
161 | ||
162 | $loader->addPath($templateDir, 'admin'); | |
163 | ||
164 | Namespaced templates can be accessed via the special | |
165 | ``@namespace_name/template_path`` notation:: | |
166 | ||
167 | $twig->render('@admin/index.html', array()); | |
168 | ||
169 | ``Twig_Loader_String`` | |
170 | ...................... | |
171 | ||
172 | ``Twig_Loader_String`` loads templates from strings. It's a dummy loader as | |
173 | the template reference is the template source code:: | |
174 | ||
175 | $loader = new Twig_Loader_String(); | |
176 | $twig = new Twig_Environment($loader); | |
177 | ||
178 | echo $twig->render('Hello {{ name }}!', array('name' => 'Fabien')); | |
179 | ||
180 | This loader should only be used for unit testing as it has severe limitations: | |
181 | several tags, like ``extends`` or ``include`` do not make sense to use as the | |
182 | reference to the template is the template source code itself. | |
183 | ||
184 | ``Twig_Loader_Array`` | |
185 | ..................... | |
186 | ||
187 | ``Twig_Loader_Array`` loads a template from a PHP array. It's passed an array | |
188 | of strings bound to template names:: | |
189 | ||
190 | $loader = new Twig_Loader_Array(array( | |
191 | 'index.html' => 'Hello {{ name }}!', | |
192 | )); | |
193 | $twig = new Twig_Environment($loader); | |
194 | ||
195 | echo $twig->render('index.html', array('name' => 'Fabien')); | |
196 | ||
197 | This loader is very useful for unit testing. It can also be used for small | |
198 | projects where storing all templates in a single PHP file might make sense. | |
199 | ||
200 | .. tip:: | |
201 | ||
202 | When using the ``Array`` or ``String`` loaders with a cache mechanism, you | |
203 | should know that a new cache key is generated each time a template content | |
204 | "changes" (the cache key being the source code of the template). If you | |
205 | don't want to see your cache grows out of control, you need to take care | |
206 | of clearing the old cache file by yourself. | |
207 | ||
208 | ``Twig_Loader_Chain`` | |
209 | ..................... | |
210 | ||
211 | ``Twig_Loader_Chain`` delegates the loading of templates to other loaders:: | |
212 | ||
213 | $loader1 = new Twig_Loader_Array(array( | |
214 | 'base.html' => '{% block content %}{% endblock %}', | |
215 | )); | |
216 | $loader2 = new Twig_Loader_Array(array( | |
217 | 'index.html' => '{% extends "base.twig" %}{% block content %}Hello {{ name }}{% endblock %}', | |
218 | 'base.html' => 'Will never be loaded', | |
219 | )); | |
220 | ||
221 | $loader = new Twig_Loader_Chain(array($loader1, $loader2)); | |
222 | ||
223 | $twig = new Twig_Environment($loader); | |
224 | ||
225 | When looking for a template, Twig will try each loader in turn and it will | |
226 | return as soon as the template is found. When rendering the ``index.html`` | |
227 | template from the above example, Twig will load it with ``$loader2`` but the | |
228 | ``base.html`` template will be loaded from ``$loader1``. | |
229 | ||
230 | ``Twig_Loader_Chain`` accepts any loader that implements | |
231 | ``Twig_LoaderInterface``. | |
232 | ||
233 | .. note:: | |
234 | ||
235 | You can also add loaders via the ``addLoader()`` method. | |
236 | ||
237 | Create your own Loader | |
238 | ~~~~~~~~~~~~~~~~~~~~~~ | |
239 | ||
240 | All loaders implement the ``Twig_LoaderInterface``:: | |
241 | ||
242 | interface Twig_LoaderInterface | |
243 | { | |
244 | /** | |
245 | * Gets the source code of a template, given its name. | |
246 | * | |
247 | * @param string $name string The name of the template to load | |
248 | * | |
249 | * @return string The template source code | |
250 | */ | |
251 | function getSource($name); | |
252 | ||
253 | /** | |
254 | * Gets the cache key to use for the cache for a given template name. | |
255 | * | |
256 | * @param string $name string The name of the template to load | |
257 | * | |
258 | * @return string The cache key | |
259 | */ | |
260 | function getCacheKey($name); | |
261 | ||
262 | /** | |
263 | * Returns true if the template is still fresh. | |
264 | * | |
265 | * @param string $name The template name | |
266 | * @param timestamp $time The last modification time of the cached template | |
267 | */ | |
268 | function isFresh($name, $time); | |
269 | } | |
270 | ||
271 | As an example, here is how the built-in ``Twig_Loader_String`` reads:: | |
272 | ||
273 | class Twig_Loader_String implements Twig_LoaderInterface | |
274 | { | |
275 | public function getSource($name) | |
276 | { | |
277 | return $name; | |
278 | } | |
279 | ||
280 | public function getCacheKey($name) | |
281 | { | |
282 | return $name; | |
283 | } | |
284 | ||
285 | public function isFresh($name, $time) | |
286 | { | |
287 | return false; | |
288 | } | |
289 | } | |
290 | ||
291 | The ``isFresh()`` method must return ``true`` if the current cached template | |
292 | is still fresh, given the last modification time, or ``false`` otherwise. | |
293 | ||
294 | .. tip:: | |
295 | ||
296 | As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface`` | |
297 | to make your loader faster when used with the chain loader. | |
298 | ||
299 | Using Extensions | |
300 | ---------------- | |
301 | ||
302 | Twig extensions are packages that add new features to Twig. Using an | |
303 | extension is as simple as using the ``addExtension()`` method:: | |
304 | ||
305 | $twig->addExtension(new Twig_Extension_Sandbox()); | |
306 | ||
307 | Twig comes bundled with the following extensions: | |
308 | ||
309 | * *Twig_Extension_Core*: Defines all the core features of Twig. | |
310 | ||
311 | * *Twig_Extension_Escaper*: Adds automatic output-escaping and the possibility | |
312 | to escape/unescape blocks of code. | |
313 | ||
314 | * *Twig_Extension_Sandbox*: Adds a sandbox mode to the default Twig | |
315 | environment, making it safe to evaluate untrusted code. | |
316 | ||
317 | * *Twig_Extension_Optimizer*: Optimizes the node tree before compilation. | |
318 | ||
319 | The core, escaper, and optimizer extensions do not need to be added to the | |
320 | Twig environment, as they are registered by default. | |
321 | ||
322 | Built-in Extensions | |
323 | ------------------- | |
324 | ||
325 | This section describes the features added by the built-in extensions. | |
326 | ||
327 | .. tip:: | |
328 | ||
329 | Read the chapter about extending Twig to learn how to create your own | |
330 | extensions. | |
331 | ||
332 | Core Extension | |
333 | ~~~~~~~~~~~~~~ | |
334 | ||
335 | The ``core`` extension defines all the core features of Twig: | |
336 | ||
337 | * :doc:`Tags <tags/index>`; | |
338 | * :doc:`Filters <filters/index>`; | |
339 | * :doc:`Functions <functions/index>`; | |
340 | * :doc:`Tests <tests/index>`. | |
341 | ||
342 | Escaper Extension | |
343 | ~~~~~~~~~~~~~~~~~ | |
344 | ||
345 | The ``escaper`` extension adds automatic output escaping to Twig. It defines a | |
346 | tag, ``autoescape``, and a filter, ``raw``. | |
347 | ||
348 | When creating the escaper extension, you can switch on or off the global | |
349 | output escaping strategy:: | |
350 | ||
351 | $escaper = new Twig_Extension_Escaper('html'); | |
352 | $twig->addExtension($escaper); | |
353 | ||
354 | If set to ``html``, all variables in templates are escaped (using the ``html`` | |
355 | escaping strategy), except those using the ``raw`` filter: | |
356 | ||
357 | .. code-block:: jinja | |
358 | ||
359 | {{ article.to_html|raw }} | |
360 | ||
361 | You can also change the escaping mode locally by using the ``autoescape`` tag | |
362 | (see the :doc:`autoescape<tags/autoescape>` doc for the syntax used before | |
363 | Twig 1.8): | |
364 | ||
365 | .. code-block:: jinja | |
366 | ||
367 | {% autoescape 'html' %} | |
368 | {{ var }} | |
369 | {{ var|raw }} {# var won't be escaped #} | |
370 | {{ var|escape }} {# var won't be double-escaped #} | |
371 | {% endautoescape %} | |
372 | ||
373 | .. warning:: | |
374 | ||
375 | The ``autoescape`` tag has no effect on included files. | |
376 | ||
377 | The escaping rules are implemented as follows: | |
378 | ||
379 | * Literals (integers, booleans, arrays, ...) used in the template directly as | |
380 | variables or filter arguments are never automatically escaped: | |
381 | ||
382 | .. code-block:: jinja | |
383 | ||
384 | {{ "Twig<br />" }} {# won't be escaped #} | |
385 | ||
386 | {% set text = "Twig<br />" %} | |
387 | {{ text }} {# will be escaped #} | |
388 | ||
389 | * Expressions which the result is always a literal or a variable marked safe | |
390 | are never automatically escaped: | |
391 | ||
392 | .. code-block:: jinja | |
393 | ||
394 | {{ foo ? "Twig<br />" : "<br />Twig" }} {# won't be escaped #} | |
395 | ||
396 | {% set text = "Twig<br />" %} | |
397 | {{ foo ? text : "<br />Twig" }} {# will be escaped #} | |
398 | ||
399 | {% set text = "Twig<br />" %} | |
400 | {{ foo ? text|raw : "<br />Twig" }} {# won't be escaped #} | |
401 | ||
402 | {% set text = "Twig<br />" %} | |
403 | {{ foo ? text|escape : "<br />Twig" }} {# the result of the expression won't be escaped #} | |
404 | ||
405 | * Escaping is applied before printing, after any other filter is applied: | |
406 | ||
407 | .. code-block:: jinja | |
408 | ||
409 | {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #} | |
410 | ||
411 | * The `raw` filter should only be used at the end of the filter chain: | |
412 | ||
413 | .. code-block:: jinja | |
414 | ||
415 | {{ var|raw|upper }} {# will be escaped #} | |
416 | ||
417 | {{ var|upper|raw }} {# won't be escaped #} | |
418 | ||
419 | * Automatic escaping is not applied if the last filter in the chain is marked | |
420 | safe for the current context (e.g. ``html`` or ``js``). ``escaper`` and | |
421 | ``escaper('html')`` are marked safe for html, ``escaper('js')`` is marked | |
422 | safe for javascript, ``raw`` is marked safe for everything. | |
423 | ||
424 | .. code-block:: jinja | |
425 | ||
426 | {% autoescape 'js' %} | |
427 | {{ var|escape('html') }} {# will be escaped for html and javascript #} | |
428 | {{ var }} {# will be escaped for javascript #} | |
429 | {{ var|escape('js') }} {# won't be double-escaped #} | |
430 | {% endautoescape %} | |
431 | ||
432 | .. note:: | |
433 | ||
434 | Note that autoescaping has some limitations as escaping is applied on | |
435 | expressions after evaluation. For instance, when working with | |
436 | concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as | |
437 | escaping is applied on the result of the concatenation, not on the | |
438 | individual variables (so, the ``raw`` filter won't have any effect here). | |
439 | ||
440 | Sandbox Extension | |
441 | ~~~~~~~~~~~~~~~~~ | |
442 | ||
443 | The ``sandbox`` extension can be used to evaluate untrusted code. Access to | |
444 | unsafe attributes and methods is prohibited. The sandbox security is managed | |
445 | by a policy instance. By default, Twig comes with one policy class: | |
446 | ``Twig_Sandbox_SecurityPolicy``. This class allows you to white-list some | |
447 | tags, filters, properties, and methods:: | |
448 | ||
449 | $tags = array('if'); | |
450 | $filters = array('upper'); | |
451 | $methods = array( | |
452 | 'Article' => array('getTitle', 'getBody'), | |
453 | ); | |
454 | $properties = array( | |
455 | 'Article' => array('title', 'body'), | |
456 | ); | |
457 | $functions = array('range'); | |
458 | $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions); | |
459 | ||
460 | With the previous configuration, the security policy will only allow usage of | |
461 | the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be | |
462 | able to call the ``getTitle()`` and ``getBody()`` methods on ``Article`` | |
463 | objects, and the ``title`` and ``body`` public properties. Everything else | |
464 | won't be allowed and will generate a ``Twig_Sandbox_SecurityError`` exception. | |
465 | ||
466 | The policy object is the first argument of the sandbox constructor:: | |
467 | ||
468 | $sandbox = new Twig_Extension_Sandbox($policy); | |
469 | $twig->addExtension($sandbox); | |
470 | ||
471 | By default, the sandbox mode is disabled and should be enabled when including | |
472 | untrusted template code by using the ``sandbox`` tag: | |
473 | ||
474 | .. code-block:: jinja | |
475 | ||
476 | {% sandbox %} | |
477 | {% include 'user.html' %} | |
478 | {% endsandbox %} | |
479 | ||
480 | You can sandbox all templates by passing ``true`` as the second argument of | |
481 | the extension constructor:: | |
482 | ||
483 | $sandbox = new Twig_Extension_Sandbox($policy, true); | |
484 | ||
485 | Optimizer Extension | |
486 | ~~~~~~~~~~~~~~~~~~~ | |
487 | ||
488 | The ``optimizer`` extension optimizes the node tree before compilation:: | |
489 | ||
490 | $twig->addExtension(new Twig_Extension_Optimizer()); | |
491 | ||
492 | By default, all optimizations are turned on. You can select the ones you want | |
493 | to enable by passing them to the constructor:: | |
494 | ||
495 | $optimizer = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR); | |
496 | ||
497 | $twig->addExtension($optimizer); | |
498 | ||
499 | Twig supports the following optimizations: | |
500 | ||
501 | * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_ALL``, enables all optimizations | |
502 | (this is the default value). | |
503 | * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_NONE``, disables all optimizations. | |
504 | This reduces the compilation time, but it can increase the execution time | |
505 | and the consumed memory. | |
506 | * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR``, optimizes the ``for`` tag by | |
507 | removing the ``loop`` variable creation whenever possible. | |
508 | * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_RAW_FILTER``, removes the ``raw`` | |
509 | filter whenever possible. | |
510 | * ``Twig_NodeVisitor_Optimizer::OPTIMIZE_VAR_ACCESS``, simplifies the creation | |
511 | and access of variables in the compiled templates whenever possible. | |
512 | ||
513 | Exceptions | |
514 | ---------- | |
515 | ||
516 | Twig can throw exceptions: | |
517 | ||
518 | * ``Twig_Error``: The base exception for all errors. | |
519 | ||
520 | * ``Twig_Error_Syntax``: Thrown to tell the user that there is a problem with | |
521 | the template syntax. | |
522 | ||
523 | * ``Twig_Error_Runtime``: Thrown when an error occurs at runtime (when a filter | |
524 | does not exist for instance). | |
525 | ||
526 | * ``Twig_Error_Loader``: Thrown when an error occurs during template loading. | |
527 | ||
528 | * ``Twig_Sandbox_SecurityError``: Thrown when an unallowed tag, filter, or | |
529 | method is called in a sandboxed template. |