Twig, add first and last class
Let's say I have a for loop like this:
{% for elem in arrMenu %}
<div class="topmenu-button">
<a href="{{ elem.url }}">{{ elem.name }}</a>
</div>
{% endfor %}
In that form, it would render something like:
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
How can twig help me to add first and last classes the the div, so that I would have a result like:
<div class="topmenu-button first"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button"><a href="url">name</a></div>
<div class="topmenu-button last"><a href="url">name</a></div>
Solution 1:
You can use the "special variables" loop.first
and loop.last
for what you want.
LINK
{% for elem in arrMenu %}
{% if loop.first %}
<div class="topmenu-button first">
{% elseif loop.last %}
<div class="topmenu-button last">
{% else %}
<div class="topmenu-button">
{% endif %}
<a href="{{ elem.url }}">{{ elem.name }}</a>
</div>
{% endfor %}
EDIT: depending how much you care about the "one case", you might need a solution like this.
{% for elem in arrMenu %}
{% set classes = ["topmenu-button"] %}
{% if loop.first %}{% set classes = classes|merge(["first"]) %}{% endif %}
{% if loop.last %}{% set classes = classes|merge(["last"]) %}{% endif %}
<div class="{{ classes|join(" ") }}">
<a href="{{ elem.url }}">{{ elem.name }}</a>
</div>
{% endfor %}
Solution 2:
Since a loop can't be first
and last
at the same time, i would prefer not to use elseif
and write (DRY - what if you have to change topmenu-button
in future?):
{% for elem in arrMenu %}
{% set append %}
{% if loop.first %}first{% endif %}
{% if loop.last %}last{% endif %}
{% endset %}
<div class="topmenu-button {{ append }}">
<a href="{{ elem.url }}">{{ elem.name }}</a>
</div>
{% endfor %}
or more concise:
{% for elem in arrMenu %}
<div class="topmenu-button {% if loop.first %}first{% endif %} {% if loop.last %}last{% endif %}">
<a href="{{ elem.url }}">{{ elem.name }}</a>
</div>
{% endfor %}
Edit: this way you'll get some extra spaces in class
attribute (it's perfectly fine btw).
Edit2: this will not handle 1-element array (first = last)
Solution 3:
If it's to manage class attribut of a tag, a ternary condition would be better.
<span class="topmenu-button {{ (loop.first) ? 'first' : '' }}">{{ item.text }}</span>