Phen
Phen

Reputation: 2373

How to check if a block is overridden in Twig?

I would like to check whether a block is overriden in a child template.

template.html.twig:

<html>
    ...
    <nav class="menu">
        {% block menu %}
        {% endblock %}
    </nav>
    ...
    <div class="contents">
        {% block contents %}
        {% endblock %}
    </div>
    ...
</html>

page1.html.twig -- contains a menu:

{% extends '::template.html.twig' %}

{% block menu %}
    <ul>
        <li>...</li>
    </ul>
{% endblock %}

{% block contents %}
    Hello World!
{% endblock %}

page2.html.twig -- does not contain a menu:

{% extends '::template.html.twig' %}

{% block contents %}
    Hello World!
{% endblock %}

I would like to show the nav element in the template, only if it is overriden in the child template (the goal is to avoid an empty <nav /> element).

The Twig syntax has a is empty test, but it only applies to variables, not blocks.

What am I doing wrong?

Upvotes: 1

Views: 2770

Answers (2)

lifo
lifo

Reputation: 2893

You could add a wrapper to your nav element and then override it in page2 to make it blank when you don't want a menu. This doesn't require an extra variable.

template.html.twig

... snip ...
{% block nav %}
<nav class="menu">
    {% block menu %}
    {% endblock %}
</nav>
{% endblock %}
... snip ...

page2.html.twig

{% extends '::template.html.twig' %}

{% block nav '' %} {# here's the kicker ... #}

{% block contents %}
    Hello World!
{% endblock %}

In any other page that has a menu you would continue to override the 'menu' block normally.

Upvotes: 1

Gerry
Gerry

Reputation: 6012

You can set a variable in your child template check for that:

{# template.html.twig #}

{% if show_menu is not empty %}
<nav class="menu">
    {% block menu %}
    {% endblock %}
</nav>
{% endif %}

{# page1.html.twig #}

{% set show_menu = true %}

Maybe you should also consider putting this markup in the block definition for a more straight-forward approach.

Upvotes: 2

Related Questions