Use Twig Extension in controller

ivoba picture ivoba · Jul 11, 2012 · Viewed 14k times · Source

I have a slugify method in an Twig Extension which i would like to use in some cases in a controller, f.e with redirects.
Is there an easy way for this?
How could i access functions from Twig Extensions in the controller?

Or do i have to make the slugify method somewere as a helper in order to use it in the code and in twig?

Answer

timaschew picture timaschew · Apr 12, 2013

Access function / logic from twig and a controller

I think there are two solutions for this, both should use the Twig_Function_Method class.

1

The first solution gilden already posted, is to encapsulate the logic into a service and make a wrapper for the Twig Extension.

2

Another solution is to use only the Twig Extension. The Twig Extensino is already a service, you have to define it as service with the special <tag name="twig.extension" />. But it's also a service, which instance you can grab by the service container. And it's also possible to inject other services:

So you have your Twig Extension / Service:

class MyTwigExtension extends \Twig_Extension
{
    private $anotherService;

    public function __construct(SecurityService $anotherService= null)
    {
        $this->anotherService = $anotherService;
    }

    public function foo($param)
    {
       // do something
       $this->anotherService->bar($param);
    }


    public function getFunctions()
    {
        // function names in twig => function name in this calss
        return array(
            'foo' => new \Twig_Function_Method($this, 'foo'),
        );
    }

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'my_extension';
    }
}

The services.xml looks like this

<service id="acme.my_extension" class="Acme\CoreBundle\Twig\Extension\MyTwigExtension">
        <tag name="twig.extension" />
        <argument type="service" id="another.service"></argument>
</service>

To acccess to the service from your controller you only have to use this:
$this->container->get('acme.my_extension')

Notice The only difference to a normal service is, that the twig extension is not lazy loaded (http://symfony.com/doc/current/cookbook/templating/twig_extension.html#register-an-extension-as-a-service)