3

In my symfony2 action, i have:

$twigCode = '<li>{{ data.value }}</li>'; //In database
$datas = array(array( 'value' => 'line 1'), array( 'value' => 'line 2'));

return $this->render(
    '...List.html.twig',
    array(
        'twigCode' => $twigCode,
        'datas' => $datas
    )
);

In my twig template, i want something like:

<ul>
{% for data in data %}
    {{ render({{ twigCode }}, {data: data}) }}
{% endfor %}
</ul>

Expected that:

<ul>
    <li>line 1</li>
    <li>line 2</li>
</ul>
Harold
  • 669
  • 1
  • 7
  • 31
  • I dont understand what you are trying to acheive ,but you can write twig code directly in the template instead of passing from controller. – Sumeet Jun 17 '15 at 09:10
  • My twig code is in a database, writed by user – Harold Jun 17 '15 at 09:20

2 Answers2

3

You could render and concatenate the twig fragments in the controller:

$templating = $this->container->get('templating');
$someTwig = '';

foreach ($datas as $data)
{
    $someTwig .= $templating->render($twigCode, $data);
}

return $this->render('...List.html.twig', array('someTwig' => $someTwig));

Then in the twig:

<ul>
    {{ someTwig | raw }}
</ul>

Otherwise, if you really want to do this in the twig you can write a Custom Twig Extension that implements a twig function 'render' so that something like your suggested twig snippet will work:

In the twig extension (you will need to register it as a service, see link above):

class MyTwigExtension extends \Twig_Extension 
{
    private $templating;

    public function__construct($templating)
    {
        $this->templating = $templating;
    }

    public function getFunctions()
    {
        return array(
            'render' => new \Twig_Filter_Method($this, 'render'), 
        );
    }

    public function render($twigFragment, array $data)
    {
        return $this->templating->render($twigFragment, $data);
    }
}

Then in the twig:

<ul>
{% for data in data %}
    {{ render(twigCode, data) | raw }}
{% endfor %}
</ul>

NB - it's possible 'render' is a reserved word for twig, so the custom twig function may need a different name.

redbirdo
  • 4,937
  • 1
  • 30
  • 34
2

You will have to use twig core or may be customized view rendering

Check below code

$loader = new Twig_Loader_Array(array(
'index.html' => 'Hello {{ name }}!',
));
$twig = new Twig_Environment($loader);

echo $twig->render('index.html', array('name' => 'Fabien'));

check here for documentation: http://twig.sensiolabs.org/doc/api.html#built-in-loaders

Sumeet
  • 1,683
  • 20
  • 27
  • Ok so it's not feasible to do it in the twig template? – Harold Jun 17 '15 at 09:33
  • 1
    Twig templates are compiled to php executable files when executing, So you cannot pass twig code in these way.Since twig engine assumes it as text. – Sumeet Jun 17 '15 at 09:35
  • Actually, it is possible, as long as the fragment you are inserting has already been 'render'ed by the twig templating engine (in which case it doesn't need further compliation) and is passed through the 'raw' filter so that it isn't encoded. – redbirdo Jun 17 '15 at 10:06
  • A simpler way of doing this (code from this answer) is to use the templating service. – redbirdo Jun 17 '15 at 10:09
  • Thank you for that answer - it helped me achieve dynamic twig code resolution :). The other ones mentioning templating service are no longer valid as of Symfony 5/Twig 3. The only change I had to do, is to use `\Twig\Loader\ArrayLoader` instead of `Twig_Loader_Array` – Axinet Dec 14 '21 at 19:29