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