Set variable in loop - symfony

I'm trying to create a json object on twig, so I need to set a variable inside a loop.
After many attempts I found this way, but it's fine when I only have two records, if I have any more you generate the problem:
{% set data = [] %}
{% for artist in artists %}
{% if loop.first %}
{%
set data = {
id : artist.id,
text : artist.name|capitalize() ~' '~ artist.surname|capitalize()
}
%}
{% else %}
{%
set data = [data,{
id : artist.id,
text : artist.name|capitalize() ~' '~ artist.surname|capitalize()
}]
%}
{% endif %}
{% endfor %}
{% set data = {results: data} %}
{{ data|json_encode|raw }}
What I want to achieve is:
{results: [{id: 1, text: "bla"},{id: 2, text: "blabla"},{id: 3, text: "blablabla"}]}
Instead I get:
{results:[[{id:1,text:"bla"},{id:2,text:"blabla"}],{id:3,text:"blablabla"}]}
Is there a way to build a json object inside twig without going crazy?
I've already tried this way .. but rewrites the object and saves in the variable only the last element:
{% set data = [] %}
{% for artist in artists %}
{%
set data = {
id : artist.id,
text : artist.name|capitalize() ~' '~ artist.surname|capitalize()
}
%}
{% endfor %}
{% set data = {results: data} %}
{{ data|json_encode|raw }}

Use merge.
{% set data = [] %}
{% for artist in artists %}
{%
set data = data|merge ([{
id : artist.id,
text : artist.name|capitalize() ~' '~ artist.surname|capitalize()
}])
%}
{% endfor %}
{% set data = {results: data} %}
{{ data|json_encode|raw }}

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?

Twig count the number of items according to a name

I have a residence table with a relationship ManyToOne residence -> requests. I would like to count the number of applications from each residence. I already start by displaying my 2 residences but I would like to count the number of applications for each residence. Here is my code.
{% set countD = [] %}
{% for key in demandes|keys %}
{% if demandes[key].residence.name not in countD %}
Résidence : <em style="color:#b94a83;">{{ demandes[key].residence.name }}</em>
<br/>
{% set countD = countD|merge([demandes[key].residence.name]) %}
{% endif %}
{% endfor %}
Thank you.
This type of logic should be implemented in your controller, otherwise can do using this:
{% set residences = [] %}
{% set demandesCount = {} %}
{% for key in demandes|keys %}
{% set name = demandes[key].residence.name %}
{% set demandesCount = demandesCount|merge({ (name) : demandesCount[name]|default(0) + 1 }) %}
{% if name not in residences %}
Résidence : <em style="color:#b94a83;">{{ name }}</em>
<br/>
{% set residences = residences|merge([(name)]) %}
{% endif %}
{% endfor %}
demandesCount will have something like this
Then use this array when you need.
If you need display the amount of demands when print the residence name then a little change is required:
{% set residences = [] %}
{% set demandesCount = {} %}
{% for key in demandes|keys %}
{% set name = demandes[key].residence.name %}
{% set demandesCount = demandesCount|merge({ (name) : demandesCount[name]|default(0) + 1 }) %}
{% set residences = residences|merge({(name) : name}) %}
{% endfor %}
{% for name in residences %}
Résidence : <em style="color:#b94a83;">{{ name }}</em> ({{ demandesCount[name] }})
<br/>
{% endfor %}
Due to the complexity of the template is advised do this type of logic in the controller, but sometimes is needed ;)

Twig - passing a parameter to a function with a dynamic variable name

I have Twig variables:
{{ totalAmountMonth0 }} ... {{ totalAmountMonth10 }}
I have a loop and I want to call this variable for example:
{{ totalAmountMonth5 }}
I want to give this variable to a function like this:
totalAmount.percentFromTotalAmount((totalAmountMonth5))
But this doesn't work:
{% for i in 0..10 %}
{{ totalAmount.percentFromTotalAmount(totalAmountMonth~i) }}
{% endfor %}
This doesn't work either:
{% for i in 0..10 %}
{{ totalAmount.percentFromTotalAmount('totalAmountMonth'~i) }}
{% endfor %}
Untested, but try this:
{% for i in 0..10 %}
{{ totalAmount.percentFromTotalAmount(attribute(_context, 'totalAmountMonth'~i)) }}
{% endfor %}
Just provide to your twig an array, which I suggest, or build it (see below example)
// use line below only if array isn't provided to twig
{% set totalAmounts = { totalAmount1, totalAmount2, ..., totalAmount10 } %} // pseudo-code; you need to declare all variables here
{% for ta in totalAmounts %}
{{ totalAmount.percentFromTotalAmount(ta) }}
{% endfor %}
Try to set that variable before and use it.
{% for i in 0..10 %}
{% set temp = 'totalAmountMonth'~i %}
{{ totalAmount.percentFromTotalAmount(temp) }}
{% endfor %}

Twig loop and building hash

i have a problem with twig syntax and merge function ... I have multiple object with 2 field category and price.
I need to create an array or hash (i guess hash is easier but ... i try both) with sum of prices for each category.
So i try many code, and my last is :
{% set test = [ {'category': 'description', 'price': '1'}, { 'category': 'abc', 'price': '2'}, { 'category':'description', 'price': '3'} ] %}
{% set listCategory={} %}
{% for line in test %}
{% set new_category = { 'category': line.category, 'price': line.price } %}
{% if loop.first %}
{% set listCategory = listCategory|merge([new_category]) %}
{% else %}
{% set flag = false %}
{% for category in listCategory %}
{% if line['category'] == new_category['category'] %}
{% set tmp = line['price'] + new_category['price'] %}
{# i try it too#}
{% set category = category|merge([tmp]) %}
{# or i try this#}
{% set category = category|merge({ (category.price) : category.price + new_category.price }) %}
{{ dump(listCategory) }}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
I try it since 3 hours and i don't know where i make an error.
When i check my array, i test if the key 'name' exist
if yes, i want to add the price of element to the hash price
if no, i want to add a new array in hash with key = 'name'
Anyone have an idea ? thx for your reading.
I think you are looking for something similar to:
{% set test = [ {'category': 'description', 'price': 1}, { 'category': 'abc', 'price': 2}, { 'category':'description', 'price': 3} ] %}
{% set listCategory={} %}
{% for line in test %}
{% set key = line.category %}
{% if listCategory[key] is defined %}
{# notice here that the key is in brackets () because otherwise it will be interpreted as the string "key" %}
{% set listCategory = listCategory|merge({(key):listCategory[line.category]+line.price}) %}
{% else %}
{% set listCategory = listCategory|merge({(key):line.price}) %}
{% endif %}
{{ key }}: {{ listCategory[key] }}
{% endfor %}

How to retrieve the value (string) of an array's element and use it to retrieve the property value of an entity?

how to retrieve the value (string) of an array's element and retrieve the property value of an entity? I tried this:
{% for item in items %} //item is an entity
{% for column in columns %} //column is just an array with name of columns
{% set columna = column.value %}
{{ item.columna }}
{% endfor %}
{% endfor %}
If you want to access dynamically a property of an object, you can use the attribute function :
{% for item in items %}
{% for column in columns %}
{{ attribute(item , column.value) }}
{% endfor %}
{% endfor %}
Try this:
{% for item in items %} //item is an entity
{% for column in columns %} //column is just an array with name of columns
{% set columna = column.value %}
{{ attribute(item, columna) }}
{% endfor %}
{% endfor %}
I recommend reading the documentation.

Resources