Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

conditionally define a block in twig 2

so heres the use case:

  • render a login form block in dynamic page structure, but only if user is not authenticated
  • block must not be defined if not authenticated (to preserve dynamic page structure)

twig 2.2
symfony 3.2


In a base template, I'm only rendering a block if its defined (not 'not emtpy')

base.html.twig

{% if block('left_sidebar') is defined %}
      <div class="col-md-2">
           {{- block('left_sidebar') -}}
      </div>
      <div class="col-md-10">
{% else %}
      <div class="col-md-12">
{% endif %}

index.html.twig

For the above to work the block cant be defined at all (which is entirely designed). The following renders the block anyway, and I cant' figure out why.

{% if not is_granted('IS_FULLY_AUTHENTICATED') %}
    {% block left_sidebar %}
        {% include ':blocks:block__login.html.twig' %}
    {% endblock %}
{% endif %}

I'm wondering if this is'nt working because of the same reason that the base template code does work. That is that the blocks are compiled before runtime, and the conditional statements are executed at runtime.

Can anyone please confirm that this I'm right? Or correct me if I'm wrong?

edit

I've tried forcing the result of the condition to both true and false, and the block is rendered in either case.

like image 369
DevDonkey Avatar asked Nov 19 '22 04:11

DevDonkey


2 Answers

so, to wrap this up, as it seems to be a problem occurring in a few places, my suspicions are correct in that its a compile/runtime issue.

Blocks are compiled and because the if statement is at runtime one cant control the other.

heres the github issue thread if anyone wants more info.

like image 175
DevDonkey Avatar answered Dec 05 '22 23:12

DevDonkey


The block() function appears to return a falsey value if nothing or only white space was output in it, so you can wrap the block in a truthiness test and in the child template make sure it is empty if you don't want it to show. Something like this worked for me:

base.html.twig:

{% if block('left_sidebar') %}
        <div class="col-md-2">
            {% block left_sidebar %}{% endblock %}
        </div>
        <div class="col-md-10">
{% else %}
        <div class="col-md-12">
{% endif %}

index.html.twig

{% block left_sidebar %}
    {% if not is_granted('IS_FULLY_AUTHENTICATED') %}
        {% include ':blocks:block__login.html.twig' %}
    {% endif %}
{% endblock %}
like image 37
tobymackenzie Avatar answered Dec 05 '22 21:12

tobymackenzie