Extending Twig
==============

Twig can be extended in many ways; you can add extra tags, filters, tests,
operators, global variables, and functions. You can even extend the parser
itself with node visitors.

.. note::

    The first section of this chapter describes how to extend Twig. If you want
    to reuse your changes in different projects or if you want to share them
    with others, you should then create an extension as described in the
    following section.

.. caution::

    When extending Twig without creating an extension, Twig won't be able to
    recompile your templates when the PHP code is updated. To see your changes
    in real-time, either disable template caching or package your code into an
    extension (see the next section of this chapter).

Before extending Twig, you must understand the differences between all the
different possible extension points and when to use them.

First, remember that Twig has two main language constructs:

* ``{{ }}``: used to print the result of an expression evaluation;

* ``{% %}``: used to execute statements.

To understand why Twig exposes so many extension points, let's see how to
implement a *Lorem ipsum* generator (it needs to know the number of words to
generate).

You can use a ``lipsum`` *tag*:

.. code-block:: twig

    {% lipsum 40 %}

That works, but using a tag for ``lipsum`` is not a good idea for at least
three main reasons:

* ``lipsum`` is not a language construct;
* The tag outputs something;
* The tag is not flexible as you cannot use it in an expression:

  .. code-block:: twig

      {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}

In fact, you rarely need to create tags; and that's good news because tags are
the most complex extension point.

Now, let's use a ``lipsum`` *filter*:

.. code-block:: twig

    {{ 40|lipsum }}

Again, it works. But a filter should transform the passed value to something
else. Here, we use the value to indicate the number of words to generate (so,
``40`` is an argument of the filter, not the value we want to transform).

Next, let's use a ``lipsum`` *function*:

.. code-block:: twig

    {{ lipsum(40) }}

Here we go. For this specific example, the creation of a function is the
extension point to use. And you can use it anywhere an expression is accepted:

.. code-block:: twig

    {{ 'some text' ~ lipsum(40) ~ 'some more text' }}

    {% set lipsum = lipsum(40) %}

Lastly, you can also use a *global* object with a method able to generate lorem
ipsum text:

.. code-block:: twig

    {{ text.lipsum(40) }}

As a rule of thumb, use functions for frequently used features and global
objects for everything else.

Keep in mind the following when you want to extend Twig:

========== ========================== ========== =========================
What?      Implementation difficulty? How often? When?
========== ========================== ========== =========================
*macro*    simple                     frequent   Content generation
*global*   simple                     frequent   Helper object
*function* simple                     frequent   Content generation
*filter*   simple                     frequent   Value transformation
*tag*      complex                    rare       DSL language construct
*test*     simple                     rare       Boolean decision
*operator* simple                     rare       Values transformation
========== ========================== ========== =========================

Globals
-------

A global variable is like any other template variable, except that it's
available in all templates and macros::

    $twig = new \Twig\Environment($loader);
    $twig->addGlobal('text', new Text());

You can then use the ``text`` variable anywhere in a template:

.. code-block:: twig

    {{ text.lipsum(40) }}

Filters
-------

Creating a filter consists of associating a name with a PHP callable::

    // an anonymous function
    $filter = new \Twig\TwigFilter('rot13', function ($string) {
        return str_rot13($string);
    });

    // or a simple PHP function
    $filter = new \Twig\TwigFilter('rot13', 'str_rot13');

    // or a class static method
    $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
    $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter');

    // or a class method
    $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']);
    // the one below needs a runtime implementation (see below for more information)
    $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);

The first argument passed to the ``\Twig\TwigFilter`` constructor is the name of the
filter you will use in templates and the second one is the PHP callable to
associate with it.

Then, add the filter to the Twig environment::

    $twig = new \Twig\Environment($loader);
    $twig->addFilter($filter);

And here is how to use it in a template:

.. code-block:: twig

    {{ 'Twig'|rot13 }}

    {# will output Gjvt #}

When called by Twig, the PHP callable receives the left side of the filter
(before the pipe ``|``) as the first argument and the extra arguments passed
to the filter (within parentheses ``()``) as extra arguments.

For instance, the following code:

.. code-block:: twig

    {{ 'TWIG'|lower }}
    {{ now|date('d/m/Y') }}

is compiled to something like the following::

    <?php echo strtolower('TWIG') ?>
    <?php echo twig_date_format_filter($now, 'd/m/Y') ?>

The ``\Twig\TwigFilter`` class takes an array of options as its last argument::

    $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options);

Environment-aware Filters
~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to access the current environment instance in your filter, set the
``needs_environment`` option to ``true``; Twig will pass the current
environment as the first argument to the filter call::

    $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $string) {
        // get the current charset for instance
        $charset = $env->getCharset();

        return str_rot13($string);
    }, ['needs_environment' => true]);

Context-aware Filters
~~~~~~~~~~~~~~~~~~~~~

If you want to access the current context in your filter, set the
``needs_context`` option to ``true``; Twig will pass the current context as
the first argument to the filter call (or the second one if
``needs_environment`` is also set to ``true``)::

    $filter = new \Twig\TwigFilter('rot13', function ($context, $string) {
        // ...
    }, ['needs_context' => true]);

    $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $context, $string) {
        // ...
    }, ['needs_context' => true, 'needs_environment' => true]);

Automatic Escaping
~~~~~~~~~~~~~~~~~~

If automatic escaping is enabled, the output of the filter may be escaped
before printing. If your filter acts as an escaper (or explicitly outputs HTML
or JavaScript code), you will want the raw output to be printed. In such a
case, set the ``is_safe`` option::

    $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);

Some filters may need to work on input that is already escaped or safe, for
example when adding (safe) HTML tags to originally unsafe output. In such a
case, set the ``pre_escape`` option to escape the input data before it is run
through your filter::

    $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);

Variadic Filters
~~~~~~~~~~~~~~~~

When a filter should accept an arbitrary number of arguments, set the
``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
last argument to the filter call as an array::

    $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) {
        // ...
    }, ['is_variadic' => true]);

Be warned that :ref:`named arguments <named-arguments>` passed to a variadic
filter cannot be checked for validity as they will automatically end up in the
option array.

Dynamic Filters
~~~~~~~~~~~~~~~

A filter name containing the special ``*`` character is a dynamic filter and
the ``*`` part will match any string::

    $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) {
        // ...
    });

The following filters are matched by the above defined dynamic filter:

* ``product_path``
* ``category_path``

A dynamic filter can define more than one dynamic parts::

    $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) {
        // ...
    });

The filter receives all dynamic part values before the normal filter arguments,
but after the environment and the context. For instance, a call to
``'foo'|a_path_b()`` will result in the following arguments to be passed to the
filter: ``('a', 'b', 'foo')``.

Deprecated Filters
~~~~~~~~~~~~~~~~~~

You can mark a filter as being deprecated by setting the ``deprecated`` option
to ``true``. You can also give an alternative filter that replaces the
deprecated one when that makes sense::

    $filter = new \Twig\TwigFilter('obsolete', function () {
        // ...
    }, ['deprecated' => true, 'alternative' => 'new_one']);

When a filter is deprecated, Twig emits a deprecation notice when compiling a
template using it. See :ref:`deprecation-notices` for more information.

Functions
---------

Functions are defined in the exact same way as filters, but you need to create
an instance of ``\Twig\TwigFunction``::

    $twig = new \Twig\Environment($loader);
    $function = new \Twig\TwigFunction('function_name', function () {
        // ...
    });
    $twig->addFunction($function);

Functions support the same features as filters, except for the ``pre_escape``
and ``preserves_safety`` options.

Tests
-----

Tests are defined in the exact same way as filters and functions, but you need
to create an instance of ``\Twig\TwigTest``::

    $twig = new \Twig\Environment($loader);
    $test = new \Twig\TwigTest('test_name', function () {
        // ...
    });
    $twig->addTest($test);

Tests allow you to create custom application specific logic for evaluating
boolean conditions. As a simple example, let's create a Twig test that checks if
objects are 'red'::

    $twig = new \Twig\Environment($loader);
    $test = new \Twig\TwigTest('red', function ($value) {
        if (isset($value->color) && $value->color == 'red') {
            return true;
        }
        if (isset($value->paint) && $value->paint == 'red') {
            return true;
        }
        return false;
    });
    $twig->addTest($test);

Test functions must always return ``true``/``false``.

When creating tests you can use the ``node_class`` option to provide custom test
compilation. This is useful if your test can be compiled into PHP primitives.
This is used by many of the tests built into Twig::

    namespace App;
    
    use Twig\Environment;
    use Twig\Node\Expression\TestExpression;
    use Twig\TwigTest;
    
    $twig = new Environment($loader);
    $test = new TwigTest(
        'odd',
        null,
        ['node_class' => OddTestExpression::class]);
    $twig->addTest($test);

    class OddTestExpression extends TestExpression
    {
        public function compile(\Twig\Compiler $compiler)
        {
            $compiler
                ->raw('(')
                ->subcompile($this->getNode('node'))
                ->raw(' % 2 != 0')
                ->raw(')')
            ;
        }
    }

The above example shows how you can create tests that use a node class. The node
class has access to one sub-node called ``node``. This sub-node contains the
value that is being tested. When the ``odd`` filter is used in code such as:

.. code-block:: twig

    {% if my_value is odd %}

The ``node`` sub-node will contain an expression of ``my_value``. Node-based
tests also have access to the ``arguments`` node. This node will contain the
various other arguments that have been provided to your test.

If you want to pass a variable number of positional or named arguments to the
test, set the ``is_variadic`` option to ``true``. Tests support dynamic
names (see dynamic filters for the syntax).

Tags
----

One of the most exciting features of a template engine like Twig is the
possibility to define new **language constructs**. This is also the most complex
feature as you need to understand how Twig's internals work.

Most of the time though, a tag is not needed:

* If your tag generates some output, use a **function** instead.

* If your tag modifies some content and returns it, use a **filter** instead.

  For instance, if you want to create a tag that converts a Markdown formatted
  text to HTML, create a ``markdown`` filter instead:

  .. code-block:: twig

      {{ '**markdown** text'|markdown }}

  If you want use this filter on large amounts of text, wrap it with the
  :doc:`apply <tags/apply>` tag:

  .. code-block:: twig

      {% apply markdown %}
      Title
      =====

      Much better than creating a tag as you can **compose** filters.
      {% endapply %}

* If your tag does not output anything, but only exists because of a side
  effect, create a **function** that returns nothing and call it via the
  :doc:`filter <tags/do>` tag.

  For instance, if you want to create a tag that logs text, create a ``log``
  function instead and call it via the :doc:`do <tags/do>` tag:

  .. code-block:: twig

      {% do log('Log some things') %}

If you still want to create a tag for a new language construct, great!

Let's create a ``set`` tag that allows the definition of simple variables from
within a template. The tag can be used like follows:

.. code-block:: twig

    {% set name = "value" %}

    {{ name }}

    {# should output value #}

.. note::

    The ``set`` tag is part of the Core extension and as such is always
    available. The built-in version is slightly more powerful and supports
    multiple assignments by default.

Three steps are needed to define a new tag:

* Defining a Token Parser class (responsible for parsing the template code);

* Defining a Node class (responsible for converting the parsed code to PHP);

* Registering the tag.

Registering a new tag
~~~~~~~~~~~~~~~~~~~~~

Add a tag by calling the ``addTokenParser`` method on the ``\Twig\Environment``
instance::

    $twig = new \Twig\Environment($loader);
    $twig->addTokenParser(new Project_Set_TokenParser());

Defining a Token Parser
~~~~~~~~~~~~~~~~~~~~~~~

Now, let's see the actual code of this class::

    class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
    {
        public function parse(\Twig\Token $token)
        {
            $parser = $this->parser;
            $stream = $parser->getStream();

            $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue();
            $stream->expect(\Twig\Token::OPERATOR_TYPE, '=');
            $value = $parser->getExpressionParser()->parseExpression();
            $stream->expect(\Twig\Token::BLOCK_END_TYPE);

            return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag());
        }

        public function getTag()
        {
            return 'set';
        }
    }

The ``getTag()`` method must return the tag we want to parse, here ``set``.

The ``parse()`` method is invoked whenever the parser encounters a ``set``
tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
``Project_Set_Node`` calls creating is explained in the next section).

The parsing process is simplified thanks to a bunch of methods you can call
from the token stream (``$this->parser->getStream()``):

* ``getCurrent()``: Gets the current token in the stream.

* ``next()``: Moves to the next token in the stream, *but returns the old one*.

* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
  the current token is of a particular type or value (or both). The value may be an
  array of several possible values.

* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
  type/value a syntax error is thrown. Otherwise, if the type and value are correct,
  the token is returned and the stream moves to the next token.

* ``look()``: Looks at the next token without consuming it.

Parsing expressions is done by calling the ``parseExpression()`` like we did for
the ``set`` tag.

.. tip::

    Reading the existing ``TokenParser`` classes is the best way to learn all
    the nitty-gritty details of the parsing process.

Defining a Node
~~~~~~~~~~~~~~~

The ``Project_Set_Node`` class itself is quite short::

    class Project_Set_Node extends \Twig\Node\Node
    {
        public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line, $tag = null)
        {
            parent::__construct(['value' => $value], ['name' => $name], $line, $tag);
        }

        public function compile(\Twig\Compiler $compiler)
        {
            $compiler
                ->addDebugInfo($this)
                ->write('$context[\''.$this->getAttribute('name').'\'] = ')
                ->subcompile($this->getNode('value'))
                ->raw(";\n")
            ;
        }
    }

The compiler implements a fluid interface and provides methods that helps the
developer generate beautiful and readable PHP code:

* ``subcompile()``: Compiles a node.

* ``raw()``: Writes the given string as is.

* ``write()``: Writes the given string by adding indentation at the beginning
  of each line.

* ``string()``: Writes a quoted string.

* ``repr()``: Writes a PHP representation of a given value (see
  ``\Twig\Node\ForNode`` for a usage example).

* ``addDebugInfo()``: Adds the line of the original template file related to
  the current node as a comment.

* ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
  usage example).

* ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
  usage example).

.. _creating_extensions:

Creating an Extension
---------------------

The main motivation for writing an extension is to move often used code into a
reusable class like adding support for internationalization. An extension can
define tags, filters, tests, operators, functions, and node visitors.

Most of the time, it is useful to create a single extension for your project,
to host all the specific tags and filters you want to add to Twig.

.. tip::

    When packaging your code into an extension, Twig is smart enough to
    recompile your templates whenever you make a change to it (when
    ``auto_reload`` is enabled).

An extension is a class that implements the following interface::

    interface \Twig\Extension\ExtensionInterface
    {
        /**
         * Returns the token parser instances to add to the existing list.
         *
         * @return \Twig\TokenParser\TokenParserInterface[]
         */
        public function getTokenParsers();

        /**
         * Returns the node visitor instances to add to the existing list.
         *
         * @return \Twig\NodeVisitor\NodeVisitorInterface[]
         */
        public function getNodeVisitors();

        /**
         * Returns a list of filters to add to the existing list.
         *
         * @return \Twig\TwigFilter[]
         */
        public function getFilters();

        /**
         * Returns a list of tests to add to the existing list.
         *
         * @return \Twig\TwigTest[]
         */
        public function getTests();

        /**
         * Returns a list of functions to add to the existing list.
         *
         * @return \Twig\TwigFunction[]
         */
        public function getFunctions();

        /**
         * Returns a list of operators to add to the existing list.
         *
         * @return array<array> First array of unary operators, second array of binary operators
         */
        public function getOperators();
    }

To keep your extension class clean and lean, inherit from the built-in
``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides
empty implementations for all methods::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
    }

This extension does nothing for now. We will customize it in the next sections.

You can save your extension anywhere on the filesystem, as all extensions must
be registered explicitly to be available in your templates.

You can register an extension by using the ``addExtension()`` method on your
main ``Environment`` object::

    $twig = new \Twig\Environment($loader);
    $twig->addExtension(new Project_Twig_Extension());

.. tip::

    The Twig core extensions are great examples of how extensions work.

Globals
~~~~~~~

Global variables can be registered in an extension via the ``getGlobals()``
method::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
    {
        public function getGlobals(): array
        {
            return [
                'text' => new Text(),
            ];
        }

        // ...
    }

Functions
~~~~~~~~~

Functions can be registered in an extension via the ``getFunctions()``
method::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        public function getFunctions()
        {
            return [
                new \Twig\TwigFunction('lipsum', 'generate_lipsum'),
            ];
        }

        // ...
    }

Filters
~~~~~~~

To add a filter to an extension, you need to override the ``getFilters()``
method. This method must return an array of filters to add to the Twig
environment::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        public function getFilters()
        {
            return [
                new \Twig\TwigFilter('rot13', 'str_rot13'),
            ];
        }

        // ...
    }

Tags
~~~~

Adding a tag in an extension can be done by overriding the
``getTokenParsers()`` method. This method must return an array of tags to add
to the Twig environment::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        public function getTokenParsers()
        {
            return [new Project_Set_TokenParser()];
        }

        // ...
    }

In the above code, we have added a single new tag, defined by the
``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
responsible for parsing the tag and compiling it to PHP.

Operators
~~~~~~~~~

The ``getOperators()`` methods lets you add new operators. Here is how to add
the ``!``, ``||``, and ``&&`` operators::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        public function getOperators()
        {
            return [
                [
                    '!' => ['precedence' => 50, 'class' => \Twig\Node\Expression\Unary\NotUnary::class],
                ],
                [
                    '||' => ['precedence' => 10, 'class' => \Twig\Node\Expression\Binary\OrBinary::class, 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
                    '&&' => ['precedence' => 15, 'class' => \Twig\Node\Expression\Binary\AndBinary::class, 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
                ],
            ];
        }

        // ...
    }

Tests
~~~~~

The ``getTests()`` method lets you add new test functions::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        public function getTests()
        {
            return [
                new \Twig\TwigTest('even', 'twig_test_even'),
            ];
        }

        // ...
    }

Definition vs Runtime
~~~~~~~~~~~~~~~~~~~~~

Twig filters, functions, and tests runtime implementations can be defined as
any valid PHP callable:

* **functions/static methods**: Simple to implement and fast (used by all Twig
  core extensions); but it is hard for the runtime to depend on external
  objects;

* **closures**: Simple to implement;

* **object methods**: More flexible and required if your runtime code depends
  on external objects.

The simplest way to use methods is to define them on the extension itself::

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        private $rot13Provider;

        public function __construct($rot13Provider)
        {
            $this->rot13Provider = $rot13Provider;
        }

        public function getFunctions()
        {
            return [
                new \Twig\TwigFunction('rot13', [$this, 'rot13']),
            ];
        }

        public function rot13($value)
        {
            return $this->rot13Provider->rot13($value);
        }
    }

This is very convenient but not recommended as it makes template compilation
depend on runtime dependencies even if they are not needed (think for instance
as a dependency that connects to a database engine).

You can decouple the extension definitions from their runtime implementations by
registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface`` instance on the
environment that knows how to instantiate such runtime classes (runtime classes
must be autoload-able)::

    class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface
    {
        public function load($class)
        {
            // implement the logic to create an instance of $class
            // and inject its dependencies
            // most of the time, it means using your dependency injection container
            if ('Project_Twig_RuntimeExtension' === $class) {
                return new $class(new Rot13Provider());
            } else {
                // ...
            }
        }
    }

    $twig->addRuntimeLoader(new RuntimeLoader());

.. note::

    Twig comes with a PSR-11 compatible runtime loader
    (``\Twig\RuntimeLoader\ContainerRuntimeLoader``).

It is now possible to move the runtime logic to a new
``Project_Twig_RuntimeExtension`` class and use it directly in the extension::

    class Project_Twig_RuntimeExtension
    {
        private $rot13Provider;

        public function __construct($rot13Provider)
        {
            $this->rot13Provider = $rot13Provider;
        }

        public function rot13($value)
        {
            return $this->rot13Provider->rot13($value);
        }
    }

    class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
    {
        public function getFunctions()
        {
            return [
                new \Twig\TwigFunction('rot13', ['Project_Twig_RuntimeExtension', 'rot13']),
                // or
                new \Twig\TwigFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
            ];
        }
    }

Testing an Extension
--------------------

Functional Tests
~~~~~~~~~~~~~~~~

You can create functional tests for extensions by creating the following file
structure in your test directory::

    Fixtures/
        filters/
            foo.test
            bar.test
        functions/
            foo.test
            bar.test
        tags/
            foo.test
            bar.test
    IntegrationTest.php

The ``IntegrationTest.php`` file should look like this::

    use Twig\Test\IntegrationTestCase;

    class Project_Tests_IntegrationTest extends IntegrationTestCase
    {
        public function getExtensions()
        {
            return [
                new Project_Twig_Extension1(),
                new Project_Twig_Extension2(),
            ];
        }

        public function getFixturesDir()
        {
            return __DIR__.'/Fixtures/';
        }
    }

Fixtures examples can be found within the Twig repository
`tests/Twig/Fixtures`_ directory.

Node Tests
~~~~~~~~~~

Testing the node visitors can be complex, so extend your test cases from
``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
`tests/Twig/Node`_ directory.

.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/3.x/tests/Fixtures
.. _`tests/Twig/Node`:     https://github.com/twigphp/Twig/tree/3.x/tests/Node
