2

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.

Borodin
  • 126,100
  • 9
  • 70
  • 144
ctwheels
  • 21,901
  • 9
  • 42
  • 77
  • To be honest, I would ask why you're manipulating your data in your view? IMO, views should be very dumb and simply render the data they're given. Data preparation should happen in controllers and/or services. I realise this doesn't necessarily help you :( – fubar Mar 27 '17 at 22:50
  • Check out this answer. http://stackoverflow.com/questions/9432534/setting-element-of-array-from-twig#answer-15807344. You apparently need to wrap your integer key in brackets. `{% set amount = amount|merge({(0): 'test'}) %}` – fubar Mar 27 '17 at 22:56
  • @fubar It's actually part of a really large report (about 1000 pages) that performs millions of calculations on the database. The PHP passes the massive amount of data into Twig and twig displays the information. We are trying to keep the data, application logic, and view separate, although it's a little challenging when you're talking about a thousand page report. The only reason we are manipulating data in the view is for manageability of code. We will be revising it again shortly to see if we can provide a better solution. – ctwheels Jun 29 '17 at 21:38

2 Answers2

2

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.

Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
  • I ended up using the above method for the time being as it seems to provide the best method that currently exists to handling arrays (even though it doesn't really relate to the array data type). Unfortunately, this means I have to create many variables representing each value of the array, which is cumbersome. But at least it works. – ctwheels Apr 03 '17 at 18:15
  • Sure. But you still can develop something in the php side, why would you develop your logic in twig? Still consider twig as something that will display things, but no more. Think read-only with twig. – Alain Tiemblo Apr 03 '17 at 19:25
  • For the most part, that's what it is being used for, but in this instance, twig is being used to render a complex report (about 1100 pages). We gather data for our reports in SQL, organize it appropriately in PHP (if necessary; i.e. multiple selects), then call the twig template passing in the correct data for report creation. The reason we have some logic in the twig file is because we are allowing specific users to edit the report template, however, we don't want them to have access to the PHP code; strictly the twig/html/pdf output – ctwheels Apr 03 '17 at 21:56
0

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.

savedario
  • 902
  • 15
  • 26