tchap
tchap

Reputation: 3432

Using Twig in a custom Twig Extension

In a Symfony2 project, I have created a service that implements Twig_ExtensionInterface so I can use it as a Twig filter, like {{ stuff|my_filter }}

In this service, I need to use the twig environnement so I could use twig templates for instance, so I injected it as one can do in a service :

in services.yml :

services:
    meta.twig.my_extension:
        class: Acme\GeneralBundle\Twig\MyExtension
        tags:
            - { name: twig.extension }
        arguments:
            twig: "@twig"

And so the service in itself looks like :

<?php

namespace Acme\GeneralBundle\Twig;

class MyExtension extends \Twig_Extension
{

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

    public function getFilters()
    {
        return array(
            'my_filter' => new \Twig_Filter_Method($this, 'myFunction'),
        );
    }

    public function myFunction($text)
    {
       return $this->twig->render($someTemplate,$someArguments);
    }
}

And I can use it in a controller like that :

$myService = $this->container->get('Acme.twig.my_extension');
$text = $myService->myFunction($someValue);

But, of course, I get a CircularReference Error when doing so:

Circular reference detected for service "Acme.twig.my_extension", 
path: "Acme.twig.my_extension -> twig".

So, what is the best way to use twig->render() function inside a custom Twig Filter ?

Thanks a lot !

Upvotes: 1

Views: 6139

Answers (1)

Jakub Zalas
Jakub Zalas

Reputation: 36191

Twig_ExtensionInterface defines the initRuntime() method which accepts the twig environment as an argument. This method is called by twig while initialising the extension.

You've extended the Twig_Extension class, which already provides an empty implementation of this method. All you have to do is overwrite it and store a reference to the twig environment for future use.

<?php

namespace Acme\GeneralBundle\Twig;

class MyExtension extends \Twig_Extension
{
    private $environment = null;

    public function initRuntime(\Twig_Environment $environment)
    {
        $this->environment = $environment;
    }

    public function getFilters()
    {
        return array(
            'my_filter' => new \Twig_Filter_Method($this, 'myFunction'),
        );
    }

    public function myFunction($text)
    {
       return $this->environment->render($someTemplate,$someArguments);
    }
}

Documentation: Creating an extension.

Upvotes: 3

Related Questions