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
Related
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
On a SaaS platform I try to create an indexpage/sitemap for a website with a lot of categories.
Since it's a SaaS platform I'm not able to use/create custom functions whatsoever.
It have to be done at the frontend.
What I try to do is divide a list of categories into a list divided in letters and digits.
So a category name starting with A will go in category "A", a category starting with a number (eg 18 years) will go in a category called "0-9". So I will get an indexpage like so:
[A]
- Alpha
- Anton
- etc..
[B]
- Beta
- Brave
- etc..
[C]
- Charlie
- Cooking
- etc..
[0-9]
- 1 year
- 20 years
- 99 years
- etc..
I managed to get this working for all letters. However it not always put numbers in the [0-9] category. My script sometimes create a seperate index for eg 0 or 7 etc. So like:
[0]
- 1 year
- 18 years
- etc..
[1]
- 2 years
- 22 years
Also the index number is wrong. So it shows 1 under 0 and 2 under 1. Instead of:
[0-9]
- 1 year
- 18 years
- 2 years
- 22 years
I just can't see why that is. So my question is how can I put [numeric] categories in a single categorie called [0-9] instead of having them in a seperate categorie?
My code upto now looks like (some filters are specific platform filters):
{# ---------------- BEGINING ------------------- #}
{% set all_categories = [] %}
{% for category in shop.categories %}
{% set all_categories = all_categories | merge({ (0): category }) %}
{% for sub in category.subs %}
{% set all_categories = all_categories | merge({ (0): sub }) %}
{% for sub_sub in sub.subs %}
{% set all_categories = all_categories | merge({ (0): sub_sub }) %}
{% for sub_sub_sub in sub_sub.subs %}
{% set all_categories = all_categories | merge({ (0): sub_sub_sub }) %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% set categories = all_categories %}
{# ---------------- SORT LOGIC ------------------- #}
{# 'categories' array will be sorted and saved as 'grouped_categories' variable #}
{% set sorted_categories = [] %}
{% for key in categories | keys %}
{% set sorted_categories = sorted_categories | merge({ (key): categories[key].title }) %}
{% endfor %}
{% set sorted_categories = sorted_categories | sort %}
{% set first_letter = '' %}
{% set grouped_categories = [] %}
{% set new_group = [] %}
{% for i in sorted_categories | keys %}
{% if(categories[i].title) %}
{% set currect_first_letter = categories[i].title | first | upper %}
{% if(currect_first_letter != first_letter) %}
{% if(new_group) %}
{% set grouped_categories = grouped_categories | merge({ (first_letter): new_group }) %}
{% endif %}
{% set first_letter = currect_first_letter %}
{% set new_group = [categories[i]] %}
{% else %}
{% set new_group = new_group | merge({ (0): categories[i] }) %}
{% endif %}
{% endif %}
{% endfor %}
{% set grouped_categories = grouped_categories | merge({ (first_letter): new_group }) %}
{# ---------------- USING ------------------- #}
<div class="single-letter">
<span class="custom-title">{{ "All themes" }}:</span>
<ul>
{% for letter in grouped_categories[1:] | keys %}
<li>{{ letter }}</li>
{% endfor %}
{% for letter in grouped_categories[:1] | keys %}
<li>{{ '0-9' }}</li>
{% endfor %}
</ul>
</div>
{% for letter in grouped_categories[1:] | keys %}
<div id="letter-{{letter}}" class="letter-wrap">
<h3 class="title">{{ letter }}</h3>
<div class="group">
<ul>
{% for category in grouped_categories[letter] %}
<li>{{ category.title }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
{% for letter in grouped_categories[:1] | keys %}
<div id="letter-{{letter}}" class="letter-wrap">
<h3 class="title">{{ '0-9' }}</h3>
<div class="group">
<ul>
{% for category in grouped_categories[letter] %}
<li>{{ category.title }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
{# ---------------- THE END ------------------- #}
UPDATE AS PER REQUEST
Updated code
{% for category in categories %}
{% set currect_first_letter = category | first | upper %}
{% if currect_first_letter in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] %}
{% set currect_first_letter = '0-9' %}
{% endif %}
{% if not (currect_first_letter in (grouped_categories | keys)) %}
{% set grouped_categories = grouped_categories | merge({ (currect_first_letter): [], }) %}
{% endif %}
{% set grouped_categories = grouped_categories | merge({ (currect_first_letter) : grouped_categories[currect_first_letter] | merge([ category, ]), }) %}
{% endfor %}
{#{% set sorted_categories = [] %}
{% for key in categories | keys %}
{% set sorted_categories = sorted_categories | merge({ (key): categories[key].title }) %}
{% endfor %}
{% set sorted_categories = sorted_categories | sort %}
{% set first_letter = '' %}
{% set grouped_categories = [] %}
{% set new_group = [] %}
{% for i in sorted_categories | keys %}
{% if(categories[i].title) %}
{% set currect_first_letter = categories[i].title | first | upper %}
{% if(currect_first_letter != first_letter) %}
{% if(new_group) %}
{% set grouped_categories = grouped_categories | merge({ (first_letter): new_group }) %}
{% endif %}
{% set first_letter = currect_first_letter %}
{% set new_group = [categories[i]] %}
{% else %}
{% set new_group = new_group | merge({ (0): categories[i] }) %}
{% endif %}
{% endif %}
{% endfor %}
{% set grouped_categories = grouped_categories | merge({ (first_letter): new_group }) %}#}
This has as result:
The merge filter only works with arrays or hashes; NULL and array given in....
You should be able to solve this if you override the currect_first_letter.
{% set currect_first_letter = categories[i].title | first | upper %}
{% if currect_first_letter in [0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, ] %}
{% set currect_first_letter = '0-9' %} {# change to same group #}
{% endif %}
demo
Okay I've gone over your code and simplified the grouping process a bit.
Here is the code I would use to combine arrays in twig
{% set grouped_categories = [] %}
{% for category in categories %}
{% set currect_first_letter = category | first | upper %}
{# ----- ADDED THIS LINE ------- #}
{% if currect_first_letter in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] %}
{% set currect_first_letter = '0-9' %}
{% endif %}
{# ----------------------------- #}
{% if not (currect_first_letter in (grouped_categories | keys)) %}
{% set grouped_categories = grouped_categories | merge({ (currect_first_letter): [], }) %}
{% endif %}
{% set grouped_categories = grouped_categories | merge({ (currect_first_letter) : grouped_categories[currect_first_letter] | merge([ category, ]), }) %}
{% endfor %}
Validation purpose:
{% for key in grouped_categories|keys %}
Key: {{ key }}
Values:
{% for value in grouped_categories[key] %}
- {{ value }}
{% endfor %}
{% endfor %}
demo
It seems if you use var in [0, 1, ...], before twig 3.X the 0 will return a false positive.
Try to use your original code, the one where everything got grouped in [0-9], but with the following statement
{% if currect_first_letter in [1, 2, 3, 4, 5, 6, 7, 8, 9] or currect_first_letter == '0' %}
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 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 %}
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 %}