<p>One way to do this is to query for the images once, and sort them into two different arrays. This uses twig's <a href="http://twig.sensiolabs.org/doc/2.x/filters/merge.html" rel="nofollow noreferrer">merge</a> filter, which is the way to add things to an array in twig.</p>

<pre><code>{% set mainImages = [] %}
{% set otherImages = [] %}

{% for image in product.productImages %}
  {% if image.productMainImage %}
    {% set mainImages = mainImages | merge([image]) %}
  {% else %}
    {% set otherImages = otherImages | merge([image]) %}
  {% endif %}
{% endfor %}
</code></pre>

<p>Then you can loop over the <code>mainImages</code> array to get the images with the lightswitch on, and the <code>otherImages</code> array to get the other images.</p>

<p>You will have three for loops, but only one database query.</p>

CC BY-SA 3.0
2017-02-17T02:02:47.273Z
2017-02-17T02:02:47.273Z
Marion Newlevant
<p>Actually, your code doesn't look inefficient to me. While Marion's solution is cool, I don't think it'll impact your performance. Craft is pretty smart about caching the results of database queries as it goes. So you could call 100 different loops thru product.productImages and not incur a performance penalty. Yay Craft!</p>

<p>Try it yourself in a test template:</p>

<pre><code>{% for i in 1..100 %}
  {% for image in product.productImages %}
    &lt;div class="small-3 column"&gt;
      &lt;a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"&gt;&lt;img src="{{image.getUrl('productPageThumbnail')}}" alt=""&gt;&lt;/a&gt;
    &lt;/div&gt;
  {% endfor %}
{% endfor %}
</code></pre>

<p>The only thing I see that would simplify your code a bit would be to include your conditional statement in the first <code>for</code> loop statement as a filter.</p>

<pre><code>{% for image in product.productImages if image.productMainImage %}
  &lt;div class="small-12 column"&gt;
    &lt;a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"&gt;&lt;img src="{{image.getUrl('productPageMainImage')}}" alt=""&gt;&lt;/a&gt;
  &lt;/div&gt;
{% endfor %}
</code></pre>

CC BY-SA 3.0
2017-02-22T10:58:29.637Z
Thanks Alex, as a matter of fact, i changed my approach. Rather than using lightswitch for a main image, i use first() and then use offset(1) for the other images. But thanks for example, i will keep in my mind.
orionlogic
CC BY-SA 3.0
2017-02-21T22:01:00.517Z
2017-02-21T22:01:00.517Z
Alex Roper
<p>I have a main product image and 4 thumbnails. Main product image is a lightswitch which is named <code>productMainImage</code>.</p>

<p>Here below i first iterate for the main image (which lightswitch is on) and than i make a second for loop for 4 thumbnails.</p>

<p>My problem is i don't like this code and it seems inefficient. I have to go out and go in for the loop because of my html stucture.</p>

<p>Can anyone help me to write this better?</p>

<pre><code>&lt;!-- Product Image --&gt;
&lt;div class="small-12 medium-5 column"&gt;
  &lt;div class="row"&gt;
    {% for image in product.productImages %}
      {% if image.productMainImage %}
        &lt;div class="small-12 column"&gt;
          &lt;a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"&gt;&lt;img src="{{image.getUrl('productPageMainImage')}}" alt=""&gt;&lt;/a&gt;
        &lt;/div&gt;
        {% endif %}
    {% endfor %}
    &lt;div class="small-12 column"&gt;
      &lt;div class="row small-collapse medium-uncollapse"&gt;
        {% for image in product.productImages %}
        &lt;div class="small-3 column"&gt;
          &lt;a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"&gt;&lt;img src="{{image.getUrl('productPageThumbnail')}}" alt=""&gt;&lt;/a&gt;
        &lt;/div&gt;
        {% endfor %}
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;!-- Product Image END --&gt;
</code></pre>

<templating><plugin-craftcommerce>
How to use better loop for my product images
# How to use better loop for my product images

(Asked by: username_0 on 2017-02-16)

I have a main product image and 4 thumbnails. Main product image is a lightswitch which is named productMainImage.
Here below i first iterate for the main image (which lightswitch is on) and than i make a second for loop for 4 thumbnails.
My problem is i don't like this code and it seems inefficient. I have to go out and go in for the loop because of my html stucture.
Can anyone help me to write this better?


  
    {% for image in product.productImages %}
      {% if image.productMainImage %}
        
          
        
        {% endif %}
    {% endfor %}
    
      
        {% for image in product.productImages %}
        
          
        
        {% endfor %}

**Tags:** templating, plugin-craftcommerce


---

## 2 answers

### Answer by username_1 on 2017-02-17. Score: 3 | Accepted answer

One way to do this is to query for the images once, and sort them into two different arrays. This uses twig's merge filter, which is the way to add things to an array in twig.
{% set mainImages = [] %}
{% set otherImages = [] %}

{% for image in product.productImages %}
  {% if image.productMainImage %}
    {% set mainImages = mainImages | merge([image]) %}
  {% else %}
    {% set otherImages = otherImages | merge([image]) %}
  {% endif %}
{% endfor %}

Then you can loop over the mainImages array to get the images with the lightswitch on, and the otherImages array to get the other images.
You will have three for loops, but only one database query.


---

### Answer by username_2 on 2017-02-21. Score: 2

Actually, your code doesn't look inefficient to me. While Marion's solution is cool, I don't think it'll impact your performance. Craft is pretty smart about caching the results of database queries as it goes. So you could call 100 different loops thru product.productImages and not incur a performance penalty. Yay Craft!
Try it yourself in a test template:
{% for i in 1..100 %}
  {% for image in product.productImages %}
    
      
    
  {% endfor %}
{% endfor %}

The only thing I see that would simplify your code a bit would be to include your conditional statement in the first for loop statement as a filter.
{% for image in product.productImages if image.productMainImage %}
  
    
  
{% endfor %}

> **Comments:**
> **username_0**: Thanks Alex, as a matter of fact, i changed my approach. Rather than using lightswitch for a main image, i use first() and then use offset(1) for the other images. But thanks for example, i will keep in my mind.  

---

