Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-02-17T02:02:47.273Z
Answers.LastActivityDate: 2017-02-17T02:02:47.273Z
Answers.UserDisplayName: Marion Newlevant
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-02-22T10:58:29.637Z
Answers.Text: 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.
Answers.UserDisplayName: orionlogic
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-02-21T22:01:00.517Z
Answers.LastActivityDate: 2017-02-21T22:01:00.517Z
Answers.UserDisplayName: Alex Roper
Body: <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>
  
Tags: <templating><plugin-craftcommerce>
Title: How to use better loop for my product images
ThreadText: # 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?
  
  ```
  <!-- Product Image -->
  <div class="small-12 medium-5 column">
    <div class="row">
      {% for image in product.productImages %}
        {% if image.productMainImage %}
          <div class="small-12 column">
            <a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"><img src="{{image.getUrl('productPageMainImage')}}" alt=""></a>
          </div>
          {% endif %}
      {% endfor %}
      <div class="small-12 column">
        <div class="row small-collapse medium-uncollapse">
          {% for image in product.productImages %}
          <div class="small-3 column">
            <a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"><img src="{{image.getUrl('productPageThumbnail')}}" alt=""></a>
          </div>
          {% endfor %}
        </div>
      </div>
    </div>
  </div><!-- Product Image END -->
  
  ```
  
  **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](http://twig.sensiolabs.org/doc/2.x/filters/merge.html) 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 username_1'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 %}
      <div class="small-3 column">
        <a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"><img src="{{image.getUrl('productPageThumbnail')}}" alt=""></a>
      </div>
    {% 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 %}
    <div class="small-12 column">
      <a class="fancybox" rel="gallery1" href="{{image.getUrl()}}"><img src="{{image.getUrl('productPageMainImage')}}" alt=""></a>
    </div>
  {% endfor %}
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks username_2, 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.  
  
  ---
  
  