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?
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;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With