I have a problem with this file : https://github.com/KnpLabs/KnpDisqusBundle/blob/master/Resources/views/js.html.twig , which I reproduced more simply, like this:
{% for test in 0..3 if true %}
{{loop.last}}
{% endfor %}
This raises the following error :
Item "last" for "Array" does not exist
Due to the condition Twig can't know how many elements will be looped over or whether an element is the last one. Thus it is not set.
I observed this use case in KnpDisqusBundle, so I think this is a regression. I don't know since which version it exists though.
The last property has been removed when using `for..if``. You example might have worked before because the if condition is always true. But as nikic said, it cannot work reliably, so it was removed.
Would it be worthwhile to update the docs on this limitation? I can take care of that.
Try doing something like
{% if loop.index > comments_or_whatever_r_u_looping|length %}this is the last{% else %} not the last{% endif %}
@markstory yeah, documenting it is a good idea.
It worked for me to find last item for List(text) type loop in Drupal 8 Twig
{% for key, item in content.field_chas_front_panel_leds if key|first != '#' %}
{% if loop.index == node.field_chas_front_panel_leds.getvalue|length %}
{{item['#markup'] }}
{% else %}
{{item['#markup'] ~ ', '}}
{% endif %}
{% endfor %}
this won't work, as node.field_chas_front_panel_leds.getvalue|length will count all items, while loop.index will be incremented only when the filter matches (which is why loop.last cannot work either)
For Drupal, just use the Twig Tweak module's "children" filter, like so:
{% for item in content.field_name | children(true) %}
{# loop.length, loop.revindex, loop.revindex0, and loop.last are now available #}
{% endfor %}
With the newest versions of Twig, that's not an issue anymore.
With the newest versions of Twig, that's not an issue anymore.
Hi, as of today with version 2.11.3 of twig, the error The "loop.last" variable is not defined when looping with a condition. is still there.
I'm not sure if you were talking about that...
@Tchekda Can you give us a small reproducer?
Hi @fabpot , thank you so much for answering that fast.
I know that this code is definitively wrong and bad but that shows clearly the error (in my case future_tournaments are not defined yet when this error appears) :
{% for tournament in future_tournaments if future_tournaments is defined %}
{% for day in tournament.date %}
{{ day.day }} {{ day.month }} {{ (loop.last == false and tournament.date|length > 1 ? 'et') }}
{% endfor %}
({{ tournament.category }}){{ (loop.last == false and future_tournaments|length > 1 ?',') }}
{% else %}
XXX
{% endfor %}
So i'm my project i removed if future_tournaments is defined that is useless because if twig sees that the varaiable is not defined, it goes to the {% else %} statement
You example is using an if condition, so the limitation still applies. You need to convert your code to use the new filter filter. In your example, the filter does not really make sense, so you need to put the condition outside the for tag.
You example is using an
ifcondition, so the limitation still applies. You need to convert your code to use the newfilterfilter. In your example, the filter does not really make sense, so you need to put the condition outside thefortag.
Oh, ok so i didn't understood well your answer, i thought you were talking about the if statement. So you're right about the filter, it does not throw any error.
Thank you for answering me, do you have a link that explains better the filter system for loops, because the documentation is still showing an if statement?
@Tchekda See https://twig.symfony.com/doc/2.x/filters/filter.html
End of the issue for me, thank you so much for helping me solving it.
Most helpful comment
@Tchekda See https://twig.symfony.com/doc/2.x/filters/filter.html