Opencart 3 TWIG: how to use AND operator - twig

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

Related

Twig 3: Break in a loop

Does anyone know how to loop through an array and find the first of an item then break the loop in twig?
Like this
Loop->find 3
- 2
- 2
- 3 - then break loop here
- 1
- 3
Try this code. It's working on the twig <= 2 version.
{% set break = false %}
{% set numbers = [2,2,3,1,3] %}
{% for number in numbers if not break %}
- {{ number }} <br/>
{% if number == 3 %}
{% set break = true %}
{% endif %}
{% endfor %}
But in Twig 3, it's not working. You can try the below code it's working for twig 3.
{% set break = false %}
{% set numbers = [2,2,3,1,3] %}
{% for number in numbers %}
{% if break == false %}
- {{ number }} <br/>
{% if number == 3 %}
{% set break = true %}
{% endif %}
{% endif %}
{% endfor %}
I have read the twig 3 document but I can't fine break/continue concept on that.
=> Output
- 2
- 2
- 3

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

TWIG REPLACE not Working

I have the following twig code:
{% set button_class = button_class_off|default('toggle toggle-thumbs-down') %}
{% set button_toggle_swap = button_toggle_swap|default(['toggle-thumbs-down', 'toggle-thumbs-up']) %}
{% if value == '1' %}
{% dump(name) %}
{% for swap in button_toggle_swap %}
{% if swap in button_class %}
{% dump(swap) %}
{% dump(button_class) %}
{% set button_class = button_class|replace({swap: ""})|trim %}
{% dump(button_class) %}
{% else %}
{% set button_class = button_class ~ ' ' ~ swap %}
{% endif %}
{% endfor %}
{% endif %}
The dump shows:
"hifi"
"toggle-thumbs-down"
"toggle toggle-thumbs-down"
"toggle toggle-thumbs-down"
I have no idea why the replace does not work. I have tried this with and without the trim. The result is that the replace of swap with "" is ignored.
Any idea what I am doing wrong here?
OK. There appears to be some missing details in the documentation. If using a variable (not an absolute string) the the variable must be wrapped in parenthesis ().
This code works:
{% set button_class = button_class_off|default('toggle toggle-thumbs-down') %}
{% set button_toggle_swap = button_toggle_swap|default(['toggle-thumbs-down', 'toggle-thumbs-up']) %}
{% if value == '1' %}
{% for swap in button_toggle_swap %}
{% if swap in button_class %}
{% set button_class = button_class|replace({(swap): ""})|trim %}
{% else %}
{% set button_class = button_class ~ ' ' ~ swap %}
{% endif %}
{% endfor %}
{% endif %}
Thanks to this answer to str_replace in twig

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