PHP - Twig change array key value - php

I am new to Twig and looking for a solution for the following (which would be very easy in PHP, however, our templates are setup in Twig)
What I'm trying to do
Edit an array value (using its index) in Twig so that it can be output after a loop.
What is happening
The array value (retrieved using its index) does not change when I try to edit the array value by index. Instead, it may append the value to the array
My code
...
{% set amount = [0,0,0] %}
{% for invoice in invoices %}
<tr>
<td>{% if invoice.age <= 10 %}{% set amount ?????? %}{% endif %}</td>
<td>{% if invoice.age > 10 and invoice.age <= 20 %}{% set amount ?????? %}{% endif %}</td>
<td>{% if invoice.age > 20 %}{% set amount ?????? %}{% endif %}</td>
</tr>
{% endfor %}
...
{{ amount[0] }}
What I've tried
I have tried the following to change the value of age[0] to no avail.
{% set amount = amount|merge({0: 'test'}) %}
{% set amount = amount|merge({0: 'test'})|keys %}
{% set amount = amount|merge({(0), 'test'}) %}
{% set amount = amount|merge({(0), 'test'})|keys %}
... and many more.
Intended outcome
I want to be able to output {{ age[0] }} at the end to display the amount total of all invoices aged 10 or less. Similarly, I would also like to output age[1] and age[2] to display amount total for all invoices aged between 10 and 20 days, and over 20 days, respectively.

In twig, always keep everything simple, without hard logic.
In your case, just create 3 variables.
{% set amount_under_10, amount_between_10_and_20, amount_over_20 = 0,0,0 %}
{% for invoice in invoices %}
<tr>
<td>{% if invoice.age <= 10 %}{% set amount_under_10 = amount_under_10 + 1 %}{% endif %}{{ invoice.age }}</td>
<td>{% if invoice.age > 10 and invoice.age <= 20 %}{% set amount_between_10_and_20 = amount_between_10_and_20 + 1 %}{% endif %}{{ invoice.age }}</td>
<td>{% if invoice.age > 20 %}{% set amount_over_20 = amount_over_20 + 1 %}{% endif %}{{ invoice.age }}</td>
</tr>
{% endfor %}
{{ amount_under_10 }}
{{ amount_between_10_and_20 }}
{{ amount_over_20 }}
See fiddle
If you need to be more generic (arbitrary number of ranges for example) don't do it in Twig. Twig is made for rendering information, no more.

See my answer here for a different approach.
I think I understand the idea behind keeping logic out of templates, but in my case I have SQL queries written by the administrator that are executed and a generic template outputs the results.
It makes more sense to calculate totals in the template.

Related

How to run For loop in twig file in php opencart to make the results should be like below

Suppose,
$a=1,2,3,4,5,6,7,8,9,10
then
in the for loop, it should run 1,2,3,4
and then 5 then 6,7,8,9 and then 10
then exit the loop.
You could use the batch and slice Twig filters for this. If you batch the results by groups of 5, then slice the first 4 and the 5th element you are able to loop through the results in the way you want.
Example code:
{% set items = [1,2,3,4,5,6,7,8,9,10] %}
{% for batch in items|batch(5) %}
<p>item 1 through 4</p>
{% for item in batch|slice(0, 4) %}
{{ item }}
{% endfor %}
<p>5th item</p>
{% for item in batch|slice(4, 1) %}
{{ item }}
{% endfor %}
{% endfor %}

Print Twig variable x times based upon randomized range

I am using Twig and Timber for a WordPress project. I have the following loop in my template that prints my custom post type titles into a HTML structure.
{% for company in companies %}
{% set dot = "<div class='company-dot'></div>" %}
{% set range = range(10, 20) %}
{{dot}}
{{random(range)}}
<div class="company">
<div class="company-dot dot-active"></div>
<p class="dot-caption">{{ company.title }}</p>
</div>
{% endfor %}
I would like to print my {{dot}} variable x amount of times based upon the number that is generated by {{random(range)}}. How can I do this?
The simplest solution would be to iterate random(range) times with a for loop:
{% for i in 0..random(range(10, 20)) %}
{{ dot }}
{% endfor %}
I don't really know Twig but my guess is that you could to the following:
{% for i in random(range) %}
{{dot}}
{% endfor %}
You already know how to use range, just use it again :
{% set dots_count = random(range) %}
{% for dot_index in range(1,dots_count) %}
{{dot}}
{% endfor %}
{{dots_count}}
Here is a fiddle : https://twigfiddle.com/ko595z

Looping on number value TWIG

I would like to loop on this variable that I have created before :
{% set divisionElement = (elementsLength/2)|round|number_format(0) %}
The output of this is a number.
After that I would like to create a loop with this value like that :
{% for i in divisionElement %}
{{dump(i}}
{% endfor %}
When I tried to dump i in my loop I have nothing result.
Try using range, If divisionElement is > 0
{% for i in range(1, divisionElement ) %}
{{ i }},
{% endfor %}

How do I make a simple count loop in Wordpress Timber(Twigg)?

How do I make a simple count loop in Wordpress Timber(Twigg)?
So basically just a loop like this:
($i = 0;0 < 3;i++){
echo $test[i];
}
You could use
{% for value in test %}
{{ value }}
{% endfor %}
that is safer than
{% for i in 0..2 %}
{{ test[i] }}
{% endfor %}
because in second version you have to care about index (is setted? and so on) whereas in the first you don't.
Of course if your final goal is to print only three elements from the array you should consider slice filter
{% for value in test|slice(0, 3) %}
{{ value }}
{% endfor %}

Twig: Update variable located earlier in code

I need to show a value at the top of a page, which needs to be updated after I have run some Twig loops in the middle of the page.
Here's an example:
<div>Total Amount: {{ totalAmount }}</div>
{% for product in products %}
{% set totalAmount = totalAmount + product.amount %}
{% endfor %}
I could compute the value in the Symfony controller, but there are certain reasons why I would prefer doing this in the Twig template.
Is the above possible with Twig? I'm sure the Twig code is executed sequentially and I may have to find a different solution. But I'd like to see if anyone has any suggestions.
Thanks,
JB
Use blocks.
In your main template (layout):
<div>Total Amount: {% block totalAmount %}{% endblock %}</div>
In your child template:
{% for product in products %}
{% set totalAmount = totalAmount + product.amount %}
{% endfor %}
{% block totalAmount %}{{ totalAmount }}{% endblock %}

Categories