Twig separation if statement - symfony

I have in template 10-20 same if statements.
Example:
{% if a == b %}
<div>text</div>
{% endif %}
other code
{% if a == b %}
<span></span>
{% endif %}
other code
{% if a == b %}
<div>text 2</div>
{% endif %}
and now if I need change condition I must change it in several places.
How can I easy separate this condition and change only in one place?

You can save the conditions result in a variable:
{% set ab_cond = a == b %}
{% if ab_cond %}
<div>text</div>
{% endif %}
other code
{% if ab_cond %}
<span></span>
{% endif %}
other code
{% if ab_cond %}
<div>text 2</div>
{% endif %}

Calculate it once, store the result as a variable, use the variable in the if statements.

Related

Twig use one value in different for loop

Since I'm using a SaaS platform I don't have much space to do things differently.
I have two for loops in Twig:
{% for option in product.options %}
{{ option.title }}
{% if option.values %}
{% for value in option.values %}
{{ value.title }}
{% endfor %}
{% endif %}
{% endfor %}
{% for variant in product.variants %}
{{ variant.stock.level }}
{% endfor %}
What I try to do is to use variant.stock.level value inside the product.options for loop to show some HTML. This value always match the corresponding index value of the other for loop. I also think that's the only way to do this.
So what I mean is.....Let's say both for loops contain 3 elements.
Option1
Option2
Option3
Variant1
Variant2
Variant3
So option1 needs to have the value from variant1.
For the end result I need to know what the value of eg Variant1 is to show some HTML like so:
{% for value in option.values %}
{% check if value from corresponding variant is greater then 0 %}
<li class="on-stock">{{ value.title }}</li>
{% else %}
<li class="out-of-stock">{{ value.title }}</li>
{% endif %}
{% endfor %}
I don't know no other way to explain this :) Any help appreciated....
You are looking for attribute.
The attribute function can be used to access a "dynamic" attribute of a variable
Since the indexes are the same, you can use loop.index0
Example for your case
{% if attribute(option.variants, loop.index0) > 0 %}
// some stuff
{% endif %}
I'm not sure if I understood you correctly but you may use key from first loop to access product.variants with the same index.
{% for key, option in product.options %}
{{ option.title }}
{% if option.values %}
{% for value in option.values %}
{{ value.title }}
{% endfor %}
{% endif %}
{{ product.variants[key].stock.level }}
{% endfor %}

Twig batch and loop index

I have a Twig for loop using the batch filter to wrap every 2 elements in a container div. I want to add a classname to every 3rd and 4th div in this for loop. However it seems you can't use loop.index when using the batch filter. Is that correct? How do you access the index then when using the batch filter?
What I tried is this:
{% for batch in blog.articles | limit(6) | batch(2) %}
<div class="blog-art-wrap row-eq-height">
{% for article in batch %}
<div class="article {% if loop.index == 3 or loop.index == 4 %}some-class{% endif %}">...... </div>
{% endfor %}
</div>
{% endfor %}
I also tried it with loop.index3 etc... But it just seems to ignore this.
Or is this because of the batches are in 2? So there's actually no index 3 and 4?? If so how do you access every 2nd batch then?
You could use the parent loop variable in order to refer to the parent context. As example:
{% for batch in blog.articles | batch(2) %}
<div class="blog-art-wrap row-eq-height">
{% for article in batch %}
<div class="article {% if loop.parent.loop.index == 3 or loop.parent.loop.index == 4 %}some-class{% endif %}">...... </div>
{% endfor %}
</div>
{% endfor %}
Try in this working twigfiddle.
Hope this help
try this:
{% set className = '' %}
{% if loop.index is divisibleby(3) or loop.index is divisibleby(4) %}
{% set className = 'some-class' %}
{% endif %}
<div class="article {{ className }}">...... </div>

Using a counter in a Twig node template

Setting up a Drupal 8 custom view for Top 4 items, I want a different layout for item 1 than the remaining. I have override files for the custom view, but for this example I'm using base files to keep it simple.
In views-view.html.twig base file we have:
<div class="view-content">
{{ rows }}
</div>
In node.html.twig base file we have:
<div {{ content_attributes.addClass('content') }}>
{{ content }}
</div>
In node.html.twig I am aiming for something like:
{% if row_counter = 1 %}
output this markup / fields
{% else %}
do something boring with the other 3 items.
{% endif %}
I was able to set row_counter in the views-view.twig.html file:
{% for row in rows %}
{% set row_counter = loop.index %}
<div{{ row.attributes }}>
{{ row_counter }}
</div>
{% endfor %}
But I need to check against the value of {{ row_counter }} in the node.html.twig file....
What other properties are available in node.html.twig to check against its position in the list?
From the documentation
The loop variable
Inside of a for loop block you can access some special variables:
Variable Description
-----------------------------------------------------------------
loop.index The current iteration of the loop. (1 indexed)
loop.index0 The current iteration of the loop. (0 indexed)
loop.revindex The number of iterations from the end of the loop (1 indexed)
loop.revindex0 The number of iterations from the end of the loop (0 indexed)
loop.first True if first iteration
loop.last True if last iteration
loop.length The number of items in the sequence
loop.parent The parent context
edit: every variable know in the parent template is also known inside an include as context is passed by default. Only macro's don't know the parent's context
controller
<?php
require __DIR__ . '/../requires/propel_standalone.php';
echo $twig->render('tests/items.html', [
'items' => [
'Abc',
'def',
'ghi',
'jkl',
'mno',
'pqr',
'stu',
'vwx',
'z',
],
]);
items.twig
<!doctype>
<html>
<head><title>Test</title></head>
<body>
{% for item in items %}
{% include "tests/item.html" %}
{% endfor %}
</body>
</html>
item.twig
{% set order = 'Nothing to report' %}
{% if loop.first %}
{% set order = 'I\'m first' %}
{% endif %}
{% if loop.last %}
{% set order = 'I\'m last' %}
{% endif %}
{% if loop.index is even %}
{% set order = 'I\'m even' %}
{% endif %}
{% if loop.index is divisible by(5) %}
{% set order = 'I can be dived by 5' %}
{% endif %}
{% if loop.index is divisible by(3) %}
{% set order = 'I can be dived by 3' %}
{% endif %}
<div>
<b>{{ loop.index }}:</b>{{ order }} - {{ item }}
</div>
You could do something like this if a class is enough:
Your views template:
{% for row in rows %}
<div class="{% if loop.index == 1 %}first_element{% endif %}">
{{ row.content }}
</div>
{% endfor %}
And then just style it appropriately.

Symfony : "if" does not work in a twig template

I'm trying to validate the size of an array before print a value, but the if instruction doesn't work. Always pass thought the if.
This is my code:
{% set size = custodian.phoneNumbers|length %}
{% if size > 3 %}
{% block phone_number3 %}{{phoneNumbers[2].phoneNumber }}{% endblock %}
{% endif %}
size is equal to 2
I try with this code and does not work as well.
{% set size = true %}
{% if size == false %}
{{size}}
{% endif %}
Please help!!!
Thanks in advance.
I found the answers myself
The block should be outside of the if.
{% block phone_type3 %}
{% if size >= 3 %}
{{ custodian.phoneNumbers[2].phoneType.value }}:
{% else %}
:
{% endif %}
{% endblock %}
{% block phone_number3 %}
{% if size >= 3 %}
<b>{{ custodian.phoneNumbers[2].phoneNumber }}</b>
{% endif %}
{% endblock %}

For every 10 records print something using Symfony2 and Twig

I'm building a page where member addresses are printed to a sheet of labels, and once a sheet is full with 14 addresses on a page, I then want to put a page break after it so that the addresses can be printed on multiple sheets of paper.
How can I achieve this using Twig?
This is my current Twig code:
{% for row in data %}
<div class="label-page">
<div class="label-section L7163">
<p>{{row.FirstName}} {{row.Surname}}</p>
<p>{{row.AddressLine1}}</p>
{% if row.AddressLine2 != NULL or row.AddressLine2 != '' %}
<p>{{row.AddressLine2}}</p>
{% endif %}
{% if row.Town != NULL or row.Town != '' %}
<p>{{row.Town}}</p>
{% endif %}
{% if row.County != NULL or row.County != '' %}
<p>{{row.County}}</p>
{% endif %}
{% if row.Postcode != NULL or row.Postcode != '' %}
<p>{{row.Postcode}}</p>
{% endif %}
</div>
</div>
{% endfor %}
You can use loop.index in your twig loop which returns the current iteration of the loop and divisible by(num)
{% for row in data %}
{% if loop.index is divisible by(10) %}
/*your page break*/
{% endif %}
{% endfor %}

Resources