access loop.index when within another loop in twig - twig

How can i access the loop's index when i'm in a second loop? like this:
{% for i in range(0, 3) %}
{% for j in range(0, 9) %}
{{ loop1.index + loop2.index }} // ?
{% endfor %}
{% endfor %}

In fact there's no need to set an extra variable. For two nested loops twig provides the so called parent.loop context.
To access the parents loop.index do this:
{% for i in range(0, 3) %}
{% for j in range(0, 9) %}
{{ loop.parent.loop.index + loop.index }}
{% endfor %}
{% endfor %}
Also refer to the documentation

set a variable which hold the first loop.index
{% for i in range(0, 3) %}
{% set loop1 = loop.index %}
{% for j in range(0, 9) %}
{{ loop1 + loop.index }}
{% endfor %}
{% endfor %}

Related

Opencart 3 TWIG: how to use AND operator

I'm trying to use the "AND" operator in TWIG in Opencart 3 and it doesn't work. Please tell me what I'm doing wrong.
I have some product attributes. And I want to make a condition that if two of the attribute with a specific ID are there, then the condition is met.
{% for attribute_group in attribute_groups %}
{% for attribute in attribute_group.attribute %}
{% if attribute.attribute_id == 2 and attribute.attribute_id == 3 %}
First condition
{% elseif attribute.attribute_id == 2 %}
Second condition
{% elseif attribute.attribute_id == 3 %}
Third condition
{% else %}
{% endif %}
{% endfor %}
{% endfor %
Here is text example:
if there is an attribute with ID equal 2 and an attribute with ID equal 3 then write "Floor/Number of floors".
if there is an attribute with ID equal 2 only then write "Floor"
if there is an attribute with ID equal 3 only then write "Numbers of floors".
Something can't be both X and Y at the same time. Furthermore this is something I'd advice you to test in the controller and not in the view.
Anyway if you wanted to do this in the view you will need to track of the found attributes. You could do this with two booleans or just add a counter.
{% set cnt = 0 %}
{% for attribute_group in attribute_groups %}
{% for attribute in attribute_group.attribute %}
{% if attribute.attribute_id == 2 or attribute.attribute_id == 3 %}
{% set cnt = cnt + 1 %}
{% endif %}
{% endfor %}
{% endfor %}
{% if cnt == 2 %}
{# do something #}
{% endif %}
You can simplify the if by using the test in
{% if attribute.attribute_id in [2, 3,] %}
Update of my answer because OP changed the requirements of the question
{% set words = [] %}
{% for attribute_group in attribute_groups %}
{% for attribute in attribute_group.attribute %}
{% if attribute.attribute_id == 2 %}
{% set words = words|merge(['Floor',]) %}
{% elseif attribute.attribute_id == 3 %}
{% set words = words|merge(['Numbers of floors',]) %}
{% endif %}
{% endfor %}
{% endfor %}
{% if words|default %}
{{ words|join('/') }}
{% endif %}
demo

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 %}

how can I use 2 loop index on twig

How can I use loop.index in this code.
{% for veri in data %}
<li>no: {{loop.index}}</li>
{% for inveri in datain %}
<li>no: {{loop.index}}</li>
{% endfor %}
{% endfor %}
.....
As pointed out by Goto u need to use loop.parent.loop as seen here
{% set data = [1,2,3,4,5,] %}
{% for d in data %}
{{ loop.index0 * (data|length + 1) + 1 }}
{% for d in data %}
{{ loop.parent.loop.index0 * (data|length + 1) + 1 + loop.index }}
{% endfor %}
{% endfor %}
twigfiddle
{% set data = [1,2,3,4,5,] %}
{% set data2 = [1,2,3,4,5,6,7,8,9] %}
{% for d in data %}
{{ loop.index0 * (data2|length + 1) + 1 }}
{% for d in data2 %}
{{ loop.parent.loop.index0 * (data2|length + 1) + 1 + loop.index }}
{% endfor %}
{% endfor %}
twigfiddle with 2 data-sets
Do you want something like this?
{% set data = [1, 2, 3, 4, 5] %}
{% set data2 = [1, 2, 3] %}
{% set i = 1 %}
{% for d in data %}
{{ i }}
{% set i = i + 1 %}
{% for d2 in data2 %}
{{ i }}
{% set i = i + 1 %}
{% endfor %}
{% endfor %}
See TwigFiddle

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 %}

for loop counter with Twig or Swig

Anyone know of a clean way to do this in Twig/Swig:
{% for(i = 0; i < 100; i++) %}
blah....
{% endfor %}
If you have a number, then you can just convert this to an array and then use Swig's standard for tag. This is simplest if you always want to 'start' the loop from 0 though.
For example:
{% set productCount = 6 %}
{% set productCountAsArray = Array(productCount) %}
{# This will run productCount times #}
{% for x, y in productCountAsArray %}
This is for number: {{ x }}
{% endfor %}
The swig docs have since (ivoba's answer) been updated and now contain special loop variables, which include loop.index:
{% for x in y %}
{% if loop.first %}<ul>{% endif %}
<li>{{ loop.index }} - {{ loop.key }}: {{ x }}</li>
{% if loop.last %}</ul>{% endif %}
{% endfor %}
http://paularmstrong.github.io/swig/docs/#tags-for
For twig its:
{% for i in 0..100 %}
* {{ i }}
{% endfor %}
From http://twig.sensiolabs.org/doc/tags/for.html
For swig the docs dont mention it yet:
https://github.com/paularmstrong/swig/blob/master/docs/tags.md#for
i cant really tell but it might be not supported in swig since its django inspired and django also seems to lack this feature nativly: https://code.djangoproject.com/ticket/5172
so i would like to pass the swig part to the next one.

Resources