Passing twig code into a twig template and rendering it

2020-05-27 symfony twig

So I have a twig template that's basically empty, and the application generates some twig code and passes this as a variable into a twig template, like this:

return $this->render('blank.html.twig', [
    'twig' => $this->generateTwig()
]);

blank.html.twig looks like this:

{{ twig }}

But when the template is rendered it just has un-rendered twig code inside, like this:

{% extends 'base.html.twig' %} {% block content %} <h1>{{ 'app-name'|trans }}...

How do you render the injected twig code in this example?

Doing a file_put_contents('blank', $this->generateTwig()) works, but this defeats the purpose of using templates.

Answers

You can solve this two ways. Either you pre-render $this->generateTwig()'s output and inject (the HTML) into the blank.html.twig template (untested pseudo):

$template = $this->get('twig')->createTemplate($this->generateTwig());
$twig = $template->render();

return $this->render('blank.html.twig', [
    'twig' => $twig,
]);

The downside of this approach is that you have to call {{ twig|raw }} in blank.html.twig, otherwise Twig will escape the HTML. Also: it feels a bit weird to pre-render a twig template before feeding it to Twig (again).

The other approach is that you load the template inside of your blank.html.twig template:

{{ include(template_from_string(twig)) }}

The template_from_string function is part of the StringLoaderExtension.

Docs here: https://twig.symfony.com/doc/3.x/recipes.html#loading-a-template-from-a-string


Edit: Thinking of it, a third approach could be even simpler if blank.html.twig is really just a file that outputs {{ twig }}:

$template = $this->get('twig')->createTemplate($this->generateTwig());
return $template->render();

Related