Reputation: 3432
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
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