<p>If you only need to assign different classes, you can achieve that with the <a href="https://twig.symfony.com/doc/3.x/functions/cycle.html" rel="nofollow noreferrer"><code>cycle</code> function</a>:</p>
<pre class="lang-twig prettyprint-override"><code>{% set gallery = entry.gallery.all() %}
{% set classes = ['unqiue1', 'unique2', 'unique3'] %}

{% for image in gallery %}
    &lt;img class=&quot;{{ cycle(classes, loop.index0) }}&quot; src=&quot;{{ image2.url }}&quot;&gt;
{% endfor %}
</code></pre>
<p>If you also need to differentiate the output based on the loop position relative to the image triplets (first, second or third), you can use the <a href="https://twig.symfony.com/doc/3.x/templates.html#math" rel="nofollow noreferrer">modulus operator</a>:</p>
<pre class="lang-twig prettyprint-override"><code>{# Position is 0, 1, or 2. #}
{% set position = loop.index0 % 3 %}

{% if position == 0 %}
    {# The current image is first in a triplet of images #}
{% endif %}
</code></pre>
<p>If you need to add some final output (for example, to close any open wrapper elements), you can use <code>loop.last</code> to check if the current item is the last one in the list:</p>
<pre class="lang-twig prettyprint-override"><code>{% if loop.last %}
    {# Close the last row. #}
    &lt;/div&gt;
{% %}
</code></pre>
<hr />
<p>As a sidenote, you usually don't need to output different classes at all or wrappers at all if you use <a href="https://css-tricks.com/snippets/css/complete-guide-grid/" rel="nofollow noreferrer">CSS grid</a> to create your layout. You can also target every third images starting with the first using <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child" rel="nofollow noreferrer"><code>:nth-child()</code></a>:</p>
<pre class="lang-css prettyprint-override"><code>.gallery__image:nth-child(3n + 1) {
    // targets very third item starting with the first one
}
</code></pre>

CC BY-SA 4.0
2023-02-09T14:28:11.550Z
This worked great, thank you!  I had use cycle before but hadn't thought about this application. 

One final thing need is put a conditional in to test if an image exists. Right now, if an image doesn't exist the layout gets broken. I assume because the last loop doesn't fire to close the html. Tried using {% if image | length %}<img  src="{{ cut1.url }}" >{% endif %} but that doesn't seem to work.
glider
CC BY-SA 4.0
2023-02-09T17:36:43.193Z
@glider You can use `loop.last` to check if you're on the last item in the row, I've updated my answer with an example. If this solves your issue, please remember to mark the answer as accepted. Thanks!
MoritzLost
CC BY-SA 4.0
2023-02-09T09:54:32.243Z
2023-02-09T17:35:19.783Z
2023-02-09T17:35:19.783Z
MoritzLost
<p>I have an unusual layout that requires formatting images 3 different ways for each 3 images. Then I need to repeat that set - if more images exist. I have a clunky way to start it now but wondered if there was a cleaner way to do it. Here's what I have so far:</p>
<pre><code>{# set 1 #}

&lt;div class=&quot;flexItem&quot;&gt;
    {% for image in entry.gallery.limit(1).all() %}
    &lt;img class=&quot;unique1&quot; src=&quot;{{ image.url }}&quot;&gt;
    {% endfor %}

&lt;div class=&quot;flexRight&quot;&gt;
    {% for image in entry.gallery.limit(1).offset(1).all() %}
    &lt;img class=&quot;unique2&quot; src=&quot;{{ image2.url }}&quot;&gt;
    {% endfor %}

    {% for image in entry.gallery.limit(1).offset(2).all() %}
    &lt;img class=&quot;unique3&quot; src=&quot;{{ image3.url }}&quot;&gt;
    {% endfor %}
&lt;/div&gt;
&lt;/div&gt;

{# set 2 if more images exist #}

&lt;div class=&quot;flexItem&quot;&gt;
    {% for image in entry.gallery.limit(1).offset(4).all() %}
    &lt;img class=&quot;unique1&quot; src=&quot;{{ image.url }}&quot;&gt;
    {% endfor %}

&lt;div class=&quot;flexRight&quot;&gt;
    {% for image in entry.gallery.limit(1).offset(5).all() %}
    &lt;img class=&quot;unique2&quot; src=&quot;{{ image2.url }}&quot;&gt;
    {% endfor %}

    {% for image in entry.gallery.limit(1).offset(6).all() %}
    &lt;img class=&quot;unique3&quot; src=&quot;{{ image3.url }}&quot;&gt;
    {% endfor %}
&lt;/div&gt;
&lt;/div&gt;

 
</code></pre>

<image>
showing a set of images with offset
# showing a set of images with offset

(Asked by: username_0 on 2023-02-09)

I have an unusual layout that requires formatting images 3 different ways for each 3 images. Then I need to repeat that set - if more images exist. I have a clunky way to start it now but wondered if there was a cleaner way to do it. Here's what I have so far:
{# set 1 #}


    {% for image in entry.gallery.limit(1).all() %}
    
    {% endfor %}


    {% for image in entry.gallery.limit(1).offset(1).all() %}
    
    {% endfor %}

    {% for image in entry.gallery.limit(1).offset(2).all() %}
    
    {% endfor %}



{# set 2 if more images exist #}


    {% for image in entry.gallery.limit(1).offset(4).all() %}
    
    {% endfor %}


    {% for image in entry.gallery.limit(1).offset(5).all() %}
    
    {% endfor %}

    {% for image in entry.gallery.limit(1).offset(6).all() %}
    
    {% endfor %}

**Tags:** image


---

## 1 answers

### Answer by username_1 on 2023-02-09. Score: 2 | Accepted answer

If you only need to assign different classes, you can achieve that with the cycle function:
{% set gallery = entry.gallery.all() %}
{% set classes = ['unqiue1', 'unique2', 'unique3'] %}

{% for image in gallery %}
    
{% endfor %}

If you also need to differentiate the output based on the loop position relative to the image triplets (first, second or third), you can use the modulus operator:
{# Position is 0, 1, or 2. #}
{% set position = loop.index0 % 3 %}

{% if position == 0 %}
    {# The current image is first in a triplet of images #}
{% endif %}

If you need to add some final output (for example, to close any open wrapper elements), you can use loop.last to check if the current item is the last one in the list:
{% if loop.last %}
    {# Close the last row. #}
    
{% %}


As a sidenote, you usually don't need to output different classes at all or wrappers at all if you use CSS grid to create your layout. You can also target every third images starting with the first using :nth-child():
.gallery__image:nth-child(3n + 1) {
    // targets very third item starting with the first one
}

> **Comments:**
> **username_0**: This worked great, thank you!  I had use cycle before but hadn't thought about this application.   One final thing need is put a conditional in to test if an image exists. Right now, if an image doesn't exist the layout gets broken. I assume because the last loop doesn't fire to close the html. Tried using {% if image | length %}<img  src="{{ cut1.url }}" >{% endif %} but that doesn't seem to work.  
> **username_1**: @username_0 You can use `loop.last` to check if you're on the last item in the row, I've updated my answer with an example. If this solves your issue, please remember to mark the answer as accepted. Thanks!  

---

