NagRock
NagRock

Reputation: 325

Dynamic block name in TWIG

I need to add multiple blocks in my template, every with different name.

{% for item from items %}
    {% block item.name %}sometext{% endblock %}
{% endfor %}

But I get error. How can I do this ?

In

Upvotes: 10

Views: 6575

Answers (4)

Carlos Llongo
Carlos Llongo

Reputation: 174

You can load blocks dynamically using the block function.

{% for item in items %}
    {{ block( item.name )|raw }}
{% endfor %}

Twig documentation for the block function

Upvotes: 6

If I understood the question correctly, you can do this (use parent context):

parent.html.twig

{% for item from items %} 
  {% set currentLoopItemName = item.name %}
  {% block item_loop %}sometext{% endblock %}
{% endfor %}

override.html.twig

{% extends "base.html" %}

{% block item_loop %} 
  {% if item.name == 'custom' %}
      // do something
  {% else %}
     {{ parent() }}
  {% endif %}
{% endblock %}

Upvotes: 1

Andrew Mellor
Andrew Mellor

Reputation: 216

I was attempting to do the same thing and found a solution using the template_from_string function.

_items.html.twig

{% for item in items %}
 {{ '{% block ' ~ item.name ~ ' %}'}}
 sometext
 {{ '{% endblock %}' }}
{% endfor %}
enter code here

page.html.twig

{% embed template_from_string(include('_items.html.twig')) %}
 {% block someItemName %} someDifferentText {% endblock %}
{% endembed %}

What's happening is the block tags are initially being created as text. Then we use the include function to get the rendered content of _items, as a string. Finally, we convert that string to a working template (which we can embed or extend).

This works because the template_from_string function will create and compile a template at runtime, where as normally twig is compiled before hand and unchanged at runtime.

Upvotes: 0

kgilden
kgilden

Reputation: 10356

Dynamic block names are not possible with Twig. There has been a discussion about it over at GitHub.

Upvotes: 10

Related Questions