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>
2
  • I dont understand what you are trying to acheive ,but you can write twig code directly in the template instead of passing from controller. Commented Jun 17, 2015 at 9:10
  • My twig code is in a database, writed by user Commented Jun 17, 2015 at 9:20

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

5 Comments

Ok so it's not feasible to do it in the twig template?
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.
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.
A simpler way of doing this (code from this answer) is to use the templating service.
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.