Replace dynamic variable in for loop - twig

I'm trying to figure out how I can retrieve the count and replace the "0" in the loop below
{% for product in products %}
{{ loop.index0 }} <--- This count too replace "0" designer.0.images
{% for key,value in designer.0.images %}
<div class="imageprodalign">{{ value }}<br>{{ key }}</div>
{% endfor %}
{% endfor %}

Related

Variable/Index within head of a loop

I have a for-loop within another for-loop and I would like the inner for-loop to go through the array test[INDEX] with [INDEX] being the index of the outer for-loop. I know I can get the loops index with the variable {{ loop.index() }}, however I do not know how to apply that within the head of my inner loop.
I've tried {% for x in test.{{ loop.index0 }} %}, but that throws me the error
Expected name or number.
Is there any way to do this?
In twig you can also use the array notation to get values from a variable
A note here is that the default loop.index is 1 indexed so you might want to use loop.index0 to get the correct offset
{% for f in foo %}
- {{ f }}: {{ bar[loop.index0] }}
{% endfor %}
As an alternative you can also get the key in the {% for key, value ... format
{% for key, value in foo %}
- {{ value }}: {{ bar[key] }}
{% endfor %}
demo
edit
As for you comment, you can succesfuly use this in any inner-loop, here is a more readable example
{% for country in countries %}
{{ country }}:
{% if cities[loop.index0]|default %}
<ul>
{% for city in cities[loop.index0] %}
<li>{{ city }}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
demo

How to access an element with an unknow name

I need to show a value from an element but his name is not always the same.
In my "competence" object, I have 4 fields, let's say field_1, field_2, field_3, field_4, but in function of an other value, I only have to display on of them.
I have the value in an other field of my "competence" object, "field_niveau_attendu" (it is set to 1, 2, 3 or 4)
I tried to use a "set" function
{% set niveau = "field_descriptif_" ~ competence.field_niveau_attendu.value %}
<p class="">{{ competence.field_competences_transverses.entity.niveau.value }}</p>
but it won't work
if in field_competences_transverses you have only 4 fields (field_1, field_2, field_3, field_4) you can try to use "for"
{% if competence.field_niveau_attendu.value is defined %}
{% set niveau = competence.field_niveau_attendu.value %}
{% for descriptif in competence.field_competences_transverses.entity %}
{% if loop.index == niveau %}
{{ descriptif.value }}
{% endif %}
{% endfor %}
{% endif %}

Increase loop index in twig

Below is my code. I want to increase J loop index in between inner loop so I have incremented J variable but it is not working.
`{% for j in 0..(products|length-1) %}
{% for f in 0..(rows-1) %}
{% set j = j + 1 %}
{% endfor %}
{% endfor %}`
Is there any other way to increase loop index?
Its not possible to alter the loop indeces of twig due to the fact of how the loops are compiled
{% for i in 1..5 %} for example gets compiled as
$context['_seq'] = twig_ensure_traversable(range(1, 5));
foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
//..
}
I do have another aproach for you to solve this with twig
{% set rows = 2 %}
{% set items = ((products|length) / rows) | round %}
{% for product in products %}
{% if loop.index0 % items == 0 %}
<div class="row">
{% endif %}
<div class="product">
{{ product }}
</div>
{% if loop.index % items == 0 or loop.last %}
</div>
{% endif %}
{% endfor %}

Use loop.index as part of template name to include with Twig?

I have an array of 3 items so in the following I'm including sub-component.twig 3 times:
{% for i in array %}
<div class="my-class">
{% include "sub-component.twig" %}
</div>
{% endfor %}
However I actually have 3 slightly different templates and I would like to load a different one for each iteration over the array:
sub-component-1.twig
sub-component-2.twig
sub-component-3.twig
When I print loop.index in the template the result is "1", "2" and "3". Can I therefore use the index to form the template name?
{% for i in array %}
<div class="my-class">
{{ loop.index }}
{% include ["sub-component-" ~ loop.index ~ ".twig"] %}
</div>
Possibly because I'm using gulp twig I had to break things out into variables for this to work.
https://github.com/zimmen/gulp-twig
{% for i in array %}
<div class="my-class">
{% set sub-component_1 = "sub-component-" %}
{% set sub-component_2 = loop.index %}
{% set sub-component_3 = ".twig" %}
{% set sub-component_full = sub-component_1 ~ sub-component_2 ~ sub-component_3 %}
{% include sub-component_full %}
</div>
{% endfor %}

Testing current value of cycle

I want to render blocks of HTML in alternate orientations. Is this the correct syntax in order to get the current value of cycle?
{% if ( {{ cycle(['odd', 'even']) }} == 'odd' ) %}
foo
{% elseif %}
bar
{% endif %}
cycle(['odd', 'even']) should not be inside {{ }} in the if
statement
cycle() should have a second parameter given that counts the amount of loops
the {% elseif %} should either have a condition or be changed to {% else %}
This is what you should do to get the code to work as you want it to (loop 10 times):
{% for i in 0..9 %}
{% if cycle(['odd', 'even'], i) == 'odd' %}
foo
{% else %}
bar
{% endif %}
{% endfor %}
If you want the for to loop objects you can use loop.index (starts at 1) instead of i:
{% for object in objects %}
{% if cycle(['even', 'odd'], loop.index) == 'odd' %}
foo
{% else %}
bar
{% endif %}
{% endfor %}
or loop.index0 (starts at 0):
{% for object in objects %}
{% if cycle(['odd', 'even'], loop.index0) == 'odd' %}
foo
{% else %}
bar
{% endif %}
{% endfor %}

Resources