David Rojo
David Rojo

Reputation: 2394

Symfony add a service that depends on TemplateEngine in twig.globals

I want to inject a service in each view, but this service depends on EngineInterface so I cannot add it to twig.globals as it throws an error of circular reference.

Here is an example:

The service:

namespace AppBundle\Utils;

use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;

class Test
{
    /** @var EngineInterface */
    private $template;

    /**
     * Test constructor.
     * @param $template
     */
    public function __construct(EngineInterface $template)
    {
        $this->template = $template;
    }

    public function render(){
        return $this->template->render('AppBundle::test.html.twig');
    }
}

And in config.yml:

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
    globals:
        test: "@AppBundle\\Utils\\Test"

And the error shown:

twig circular reference error

So, how can I inject this service in all views. Of course I could inject the container and get the templating service from the container, but I would like to avoid the container injection.

Thank you.

Upvotes: 0

Views: 247

Answers (1)

Tobias Xy
Tobias Xy

Reputation: 2069

Your service basically just includes the test.html.twig template into another template.

Twig already provides a built-in function for that. Instead of

{{ test.render() }}

You could just do this for the same effect, but without the need for a custom service:

{{ include('AppBundle::test.html.twig') }}

If you don't want to provide the template every time you can create a macro in a "util.twig" template file:

{% macro render() %}
    {{ include('AppBundle::test.html.twig') }}
{% endmacro %}

and use it in your template:

{% import "util.twig" as util %}

...

{{ util.render() }}

Upvotes: 1

Related Questions