Home » Php » Render a block of a “parent” template from a “child” template in Twig

Render a block of a “parent” template from a “child” template in Twig

Posted by: admin October 26, 2017 Leave a comment

Questions:

I have two templates:

Fields.html.twig, which includes a child template.

{% block important %}
  This block should be renderable from the sub template
{% endblock important %}

{% include 'XButton.html.twig' %}

XButton.html.twig, which needs to render blocks defined in the template that includes it.

block('important')

It seems like an included template isn’t able to simply render blocks of whoever included it.
How can the parent template pass the full context to the child, so that the child can access the blocks defined in the parent?

Answers:

What you’re trying to go it’s impossible, because the included template has no way to know about blocks defined in other templates…

You’ll need to structure your code a bit differently, so that the contents of the block are defined in the parent somehow – you have at least a couple of options:

Using set and include: https://twigfiddle.com/l536np

Fields.html.twig

{% set important %}
    You define the child content as a variable in the parent...
{% endset %}

{% include 'XButton.html.twig' %}

XButton.html.twig

{{ important }}

Using embed: https://twigfiddle.com/y9pp6p

Fields.html.twig

{% embed 'XButton.html.twig' %}
    {% block important %}
        You define the block content in the parent...
    {% endblock %}
{% endembed %}

XButton.html.twig

{{ block('important') }}

Questions:
Answers:

You can do it with include by passing the parent template name

{% block important %}
  This block should be renderable from the sub template
{% endblock important %}

{% include 'XButton.html.twig' with {'parent': _self} %}

And then use it in the include template

{{ block('important', parent) }}

Although this way the content of the block will be rendered twice – once when you define it in the parent, and once again in the child – see https://twigfiddle.com/6t0l6p