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