channa ly
channa ly

Reputation: 9937

How to check if a block exists in a twig template - Symfony2

Imagine I have something like this in my twig template

{% block posLeft %}
   -----
{%endblock%}

Is there any way to check for existance of the posLeft block without calling to:

block("posLeft") 

And check the return value of the posBlock to varify the existance. I am a newbie in Symfony2 + Twig.

Upvotes: 52

Views: 42683

Answers (7)

Josh Harrison
Josh Harrison

Reputation: 6004

The accepted answer didn't work for me in Twig 3.3.10, throwing an error that the block wasn't defined.

To solve this and define a block whose contents are conditionally wrapped in a container, only if any block content is set, this worked:

Parent template with block definition and wrapper element

{# parent.twig #}

<h1>Hello. I am the parent.</h1>

{% if block('sidebar') is not empty %}                                 
  <div class="sidebar-container">                                               
    {% block sidebar %}{% endblock %}                                  
  </div>                                                                    
{% endif %}

Child template setting block content

{% extends 'parent.twig' %}

{% block sidebar %}
  Sidebar content from child template
{% endblock %}

Output – block content inside wrapper:

<h1>Hello. I am the parent.</h1>

<div class="sidebar-container">
  Sidebar content from child template
</div>

Child template not setting block content

{% extends 'parent.twig' %}

{# sidebar block not set in this one... #}

Output – no empty wrapper element:

<h1>Hello. I am the parent.</h1>

Upvotes: -1

user6458657
user6458657

Reputation: 169

First check, which Twig version you are using inside your Symfony project, because the answers here are only for Twig 1.

If you are using Twig 2 you are lucky. According to the Twig documentation, you can use the defined test to check if the block exists in the current template context.

{% if block("dynamic") is defined %}
   ...
{% endif %}

I have written a little TwigExtension to check if the block gets called inside the if statement and it seems like Twig only really checks if the block exists and does not call it.

The link to the docs: https://twig.symfony.com/doc/2.x/functions/block.html

If you are using Twig 1, the old answer at https://stackoverflow.com/a/13806784/6458657 is still correct.

Upvotes: 16

tlorens
tlorens

Reputation: 552

Twig 2.x

{{ (block("posLeft")) ?? '' }}

If you want to display a block if it's defined or not in one line. Might be a little kludgy but satisfies my needs without a bunch of if..then logic.

Upvotes: 9

DevDonkey
DevDonkey

Reputation: 4880

The other answers here do not work for twig 2.1 (I've not tested on ~2.0), so here's a small update:

{% if block('dynamic') is defined %}
    {{ block('dynamic')|raw }}
{% endif %}

Note that the line to render the block is not:

{% block dynamic %}
    {#  this wont work  #}
{% endblock %}

This wont work because the block will be rendered during compile, and so the test will return true that it exists (as its tested at runtime). So you need to render the block with {{ block('dynamic')|raw }} instead as this doesn't actually define the block in the template.

Upvotes: 21

Dimitry K
Dimitry K

Reputation: 2356

Just want to provide another example which worked for me.

<body
{%  if block('ngapp') is not empty  %}ng-app="{% block ngapp %}{% endblock %}"{% endif %}
>

This allows me in child templates declare {% block ngapp 'myApp' %} and have it displayed within parent.

This was needed because on some pages I was bootstrapping Angular manually via (angular.bootstrap('moduleName', rootElement)) and Angular does not like empty ng-app='' directive and breaks in weird ways.

Upvotes: 2

valdas.mistolis
valdas.mistolis

Reputation: 1341

You can do it like this:

{% if block('posLeft') %}
  ...
{% endif %}

But it is not efficient if you need output of rendered block. So if you will need block output you should assign it to variable in the first place and then do assertions

Upvotes: 20

insertusernamehere
insertusernamehere

Reputation: 23600

You can solve it like this, if you want to display a certain block only if it has content. Hope, this is what you're looking for.

Example index.html.twig

{% set _block = block('dynamic') %}
{% if _block is not empty %}
    {{ _block|raw }}
{% endif %}

Example part.html.twig

{% extends "index.html.twig" %}

{% block dynamic %}
    Block content goes here.
{% endblock %}

Upvotes: 88

Related Questions