Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Twig: Selecting certain blocks and rendering them

Tags:

I am intergrating the twig templating engine into a PHP application. In particular, I would like to use the twig engine to render forms.

Having had a look at how symfony2 uses twig to render form widgets, they have a huge template file which contains all the widgets like so:

(...) {% block password_widget %} {% spaceless %}     {% set type = type|default('password') %}     {{ block('field_widget') }} {% endspaceless %} {% endblock password_widget %}  {% block hidden_widget %}     {% set type = type|default('hidden') %}     {{ block('field_widget') }} {% endblock hidden_widget %}  {% block email_widget %} {% spaceless %}     {% set type = type|default('email') %}     {{ block('field_widget') }} {% endspaceless %} {% endblock email_widget %}  {% block test_widget %} {% spaceless %}    <div>      {{test}}    <div> {% endspaceless %} {% endblock test_widget %}  (...) 

The question I have is how can I "grab" blocks out of this template and render them?

So far, I am able to load the template, and call get blocks to get all the blocks:

twig = new \Twig_Environment($loader, array('cache' => 'cache')); $template = $twig->loadTemplate('view\form_div_layout.html.twig'); //var_dump($template->getBlocks()); //try getting all blocks $template->displayBlock('test_widget', array('test' => 'test')); echo $template->render(); 

Unfortunately, I am not able to render just the 'test_widget' block in this case. What should I do to retrieve the 'test_widget' block from the template and then insert it into a different template to render the whole form?

like image 215
F21 Avatar asked Sep 28 '11 05:09

F21


2 Answers

Turns out that one should use $template->renderBlock('blockname', array('test' => 'test')); instead. This will make twig render that block and then return a string containing the markup for that block. One can then use echo to display it or insert it into other templates.

Full example:

$loader = new \Twig_Loader_Filesystem(array('/my-template-root')); $twig = new \Twig_Environment($loader, array('debug' => true)); $template = $twig->loadTemplate('view\form_div_layout.html.twig'); $result = $template->renderBlock('blockname', array('test' => 'test')); echo $result; 
like image 111
F21 Avatar answered Sep 19 '22 15:09

F21


If you are using Symfony and want to be able to still have access to the global variables (app, app.user, etc) then this works great:

private function renderBlock($template, $block, $params = []) {     /** @var \Twig\Environment $twig */     $twig = $this->get('twig');     /** @var \Twig\TemplateWrapper $template */     $template = $twig->load($template);      return $template->renderBlock($block, $twig->mergeGlobals($params)); } 

I just added this has a private function on my controller. Works great. Thanks to @F21 for pointing me in the right direction.

like image 30
Skylord123 Avatar answered Sep 17 '22 15:09

Skylord123