Symfony : "if" does not work in a twig template - symfony

I'm trying to validate the size of an array before print a value, but the if instruction doesn't work. Always pass thought the if.
This is my code:
{% set size = custodian.phoneNumbers|length %}
{% if size > 3 %}
{% block phone_number3 %}{{phoneNumbers[2].phoneNumber }}{% endblock %}
{% endif %}
size is equal to 2
I try with this code and does not work as well.
{% set size = true %}
{% if size == false %}
{{size}}
{% endif %}
Please help!!!
Thanks in advance.

I found the answers myself
The block should be outside of the if.
{% block phone_type3 %}
{% if size >= 3 %}
{{ custodian.phoneNumbers[2].phoneType.value }}:
{% else %}
:
{% endif %}
{% endblock %}
{% block phone_number3 %}
{% if size >= 3 %}
<b>{{ custodian.phoneNumbers[2].phoneNumber }}</b>
{% endif %}
{% endblock %}

Related

Is there a way to define logic in a block rather than in a bunch of individual tags?

For Example I have quite a lot of logic that looks like this
{% set allowed_observations = ["PAR;101;ZN_GYM", "PAR;101;ZN_CARDIOGYM", "PAR;101;0;G15"] %}
{% set allowed_observations_names = ["Downstairs Gym", "Upstairs Gym (Cardio)", "Swimming Pool"] %}
{% for observation in observations %}
{% if (observation.location.locationCode in allowed_observations) %}
{% if ("HeadCount" in observation.observationTag) %}
{% set name = "" %}
{% for key,value in allowed_observations %}
{% if (value == observation.location.locationCode) %}
{% set name = allowed_observations_names[key] %}
{% endif %}
{% endfor %}
{% set data = data | push({
name: name,
location: observation.location.locationCode,
value: observation.value
}) %}
{% endif %}
{% endif %}
{% endfor %}
I was wondering if you can just do a single {% ...all code... %} type thing, using ; for line breaks or something?

Can't get global variables in twig to work

So I have Twig running on top of Symfony 2.7. In the output html I'd like to have a few modules of text and in the last module I want some summary from all the previous ones (some data from all the previous modules' Entities) and I figured I'd append these summaries to a global variable while generating modules themselves to avoid a second loop. The code I'm using:
{% extends 'base.html.twig' %}
{% set list = '' %} {# HERE I SET A GLOBAL VAR #}
{% block body %}
<section>
<h2>{% trans %}MODULES{% endtrans %}</h2>
{% for m in plan.Modules %}
{{- block('module') -}}
{{ list }} {# HERE JUST FOR TESTING - IT'S EMPTY #}
{% endfor %}
</section>
{{ list }} {# HERE I WANT IT DISPLAYED, YET IT'S EMPTY :( #}
{% endblock %}
{% block module %}
<h3>{{ m.Module.title }}</h3>
{# HERE SOME MODULE TEXT I GET FROM COMPLICATED RELATIONS #}
{% if m.Module.list %}
{% set temp %}
{{ m.Module.shortTitle }}<br/>
{% endset %}
{% set list = list~temp %}
{% for l in m.Module.list %}
{% set temp %}
{{ l }}
{% endset %}
{% set list = list~temp %}
{% endif %}
{% endfor %}
{% endif %}
{{ list }} {# HERE IT'S WORKING #}
{% endblock %}
Any ideas?

Simple Twig Logic issue

I'am using following code to set selectedGallery to a defaultValue. The default Value should be galleryData's first Element.
Sadly it doesn't work. selectedGallery does not exist after the snipped run through...
Thanks for help
{% if selectedGallery is not defined %}
{% for gallery in galleryData|keys|slice(0, 1) %}
{% set selectedGallery = gallery %}
//if i access galleryData here, it exists ?!
{% endfor %}
{% endif %}
later the same file:
<div id="{{idPref}}PictureBox" class="backA">
{% block pictureBox %}
{% for picture in galleryData[selectedGallery] %}
{{selectedGallery}}
{% endfor %}
{% endblock %}
Symfony says that the variable doesn't exists.
Try:
First:
{% if selectedGallery is not defined %}
{% set selectedGallery = galleryData|keys|first %}
{# ... #}
http://twig.sensiolabs.org/doc/filters/first.html
Later:
<div id="{{idPref}}PictureBox" class="backA">
{% block pictureBox %}
{% for picture in attribute(galleryData, selectedGallery) %}
{{picture}}
{% endfor %}
{% endblock %}
{# ... #}
http://twig.sensiolabs.org/doc/functions/attribute.html

Twig equality if..else in symfony 2 gives both results

I'm using Symfony2 with Twig and when trying to determine the class that should be a div Twig says that all 4 classes are active even beeing in an if..else clause.
Redirect has only 1 value. I checked the syntax and I think it's correct so maybe I'm missing something.
It's correct my code or is something wrong in the Twig comparision (equality or if..else clause)?
Here is the Twig code:
{% if redirect == 'a' %}
{% block classA 'active' %}
{% elseif redirect == 'b' %}
{% block classB 'active' %}
{% elseif redirect == 'c' %}
{% block classC 'active' %}
{% else %}
{% block classD 'active' %}
{% endif %}
And the controller code:
[...]
$redirect = "a";
return $this->render('FrontendBundle:Default:delete.html.twig', array(
'id' => $id,
'redirect' => $redirect,
'text' => $text)
);
Edited.
Solution
I found that it's not possible to use if clauses out of a block, so the solution goes ahead using one block for each class.
I've also thought that a better solution would be to use a dynamic name block, but i read that's not possible.
Finally I found this that solve my problem in a different way: http://peter-hoffmann.com/2012/highlight-active-menu-item-with-twig-and-silex.html
Kind regards.
Even though this question is old, I want to clarify a few things, since there is no real answer provided.
The underlying problem here is that block is evaluated during compile time, while if is evaluated during run-time. This means that blocks are always defined, one cannot define blocks conditionally. That is also the reason why blocks cannot have dynamic names.
With the template from the question, this is not a problem:
classes.html.twig:
{% if redirect == 'a' %}
{% block classA %}active{% endblock %}
{% elseif redirect == 'b' %}
{% block classB %}active{% endblock %}
{% elseif redirect == 'c' %}
{% block classC %}active{% endblock %}
{% else %}
{% block classD %}active{% endblock %}
{% endif %}
If we render this, we get 'active', i.e. the expected output. While each block is defined, only one of them is rendered, because of the if. The problem is only revealed if we have inheritance. So let's say we have the following parent template (I assume something like that was used by the poster):
parent.html.twig:
{% block classA %}{% endblock %}
{% block classB %}{% endblock %}
{% block classC %}{% endblock %}
{% block classD %}{% endblock %}
And change our extending template to extend this (also added classE for demonstration purposes):
classes.html.twig:
{% extends "parent.html.twig" %}
{% if redirect == 'a' %}
{% block classA %}active{% endblock %}
{% elseif redirect == 'b' %}
{% block classB %}active{% endblock %}
{% elseif redirect == 'c' %}
{% block classC %}active{% endblock %}
{% else %}
{% block classD %}active{% endblock %}
{% endif %}
{% block classE %}undefined{% endblock %}
Now, if we render classes.html.twig, we get 'activeactiveactiveactive'. As before, the blocks are all defined with 'active', but the parent template has no conditional rendering, so all of them are shown. Block 'classE' is not rendered, because it is not defined in the parent template.
To fix this, one needs to essentially swap the if and block statements.
{% extends "parent.html.twig" %}
{% block classA %}
{% if redirect == 'a' %}
active
{% endif %}
{% endblock %}
{% block classB %}
{% if redirect != 'a' and redirect == 'b' %}
active
{% endif %}
{% endblock %}
{% block classC %}
{% if redirect != 'a' and redirect != 'b' and redirect == 'c' %}
active
{% endif %}
{% endblock %}
{% block classD %}
{% if redirect != 'a' and redirect != 'b' and redirect != 'c' %}
active
{% endif %}
{% endblock %}
Sadly, we lose the if/else structure when we do this, so we have to write more conditions. To fix this, we can add an intermediate step using a variable.
{% extends "classes.html.twig" %}
{% if redirect == 'a' %}
{% set render = 'a' %}
{% elseif redirect == 'b' %}
{% set render = 'b' %}
{% elseif redirect == 'c' %}
{% set render = 'c' %}
{% else %}
{% set render = 'd' %}
{% endif %}
{% block classA %}
{% if render == 'a' %}
active
{% endif %}
{% endblock %}
{% block classB %}
{% if render == 'b' %}
active
{% endif %}
{% endblock %}
{% block classC %}
{% if render == 'c' %}
active
{% endif %}
{% endblock %}
{% block classD %}
{% if render == 'd' %}
active
{% endif %}
{% endblock %}
I'm not sure if you're taking the most efficient approach for this kind of behavior, but regardless, shouldn't your blocks be defined like this?
{% block classA %}active{% endblock %}

Customization of a form widget in Symfony2/Twig

In my form template:
{% block field_label %}
{% spaceless %}
<label {{ block('widget_attributes') }}></label>
{% endspaceless %}
{% endblock %}
I need to add some extra class attributes and, of course, display the label (possibly translated). I've found that {{ block('widget_attributes') }} stores a string of attributes of the actual label.
Any chance to get an array type to easily modify it? Where i can find all block names to customize the appearance to fit my needs? Thanks for helping.
Nevermind Notepad++ helped me to find the file:
vendor\symfony\src\Symfony\Bridge\Twig\Resources\views
Three types of label defined:
{# Labels #}
{% block generic_label %}
{% spaceless %}
{% if required %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %}
{% endif %}
<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>{{ label|trans }}</label>
{% endspaceless %}
{% endblock %}
{% block field_label %}
{% spaceless %}
{% set attr = attr|merge({'for': id}) %}
{{ block('generic_label') }}
{% endspaceless %}
{% endblock field_label %}
{% block form_label %}
{% spaceless %}
{{ block('generic_label') }}
{% endspaceless %}
{% endblock form_label %}

Resources