Search code examples
conditional-statementstwigrepeat

Repeating structure with extra div and alternating content


Based on the solution in this post: https://stackoverflow.com/a/72855239/5160621 I have a structure of repeating items with extra divs after every fourth item:

{% for values in items|batch(4) %}
    {% for value in values %}
        <div>{{ value }}</div>
    {% endfor %}
    {% if loop.index0 is even %}
        <div class="xyz">Div 1</div>
    {% else %}
        <div class="xyz">Div 2</div>
    {% endif %}
{% endfor %}

Now I want to display alternating contents in the second extra div, something like:

{% for values in items|batch(4) %}
    {% for value in values %}
        <div>{{ value }}</div>
    {% endfor %}
    {% if loop.index0 is even %}
        <div class="xyz">Div 1</div>
    {% else %}
        {% first appearance show: %}<div class="xyz">Div 2</div>
        {% then show: %}<div class="xyz">Div 3</div>
    {% endif %}
{% endfor %}

Is it possible?


Solution

  • You can solve this in a couple ways.

    1. Use an extra "flag" variable

    Just define the "flag" outside the for-loop. You can toggle the value of the flag with the following snippet:

    {% set flag = false %}
    ...
    ...
    {% set flag = not flag %}
    

    This will set the flag to true when the flag was false and vice versa.

    {% set alternate = false %}
    
    {% for values in items|batch(4) %}
        {% for value in values %}
            <div>{{ value }}</div>
        {% endfor %}
        {% if loop.index0 is even %}
            <div class="xyz">Div 1</div>
        {% else %}
            {% if alternate %}
                <div class="xyz">Div 3</div>        
            {% else %}
                <div class="xyz">Div 2</div>
            {% endif %}
            
            {% set alternate = not alternate %}
        {% endif %}
    {% endfor %}
    

    demo


    1. Use the already existing loop variable

    If you count out when the div 3 should occur you'll notice the div should be displayed at the following 0-indexed indices:

    3, 7, 11, 15, ...
    

    But if you use loop.index instead of loop.index0, you can see each index is divisible by 4:

    4, 8, 12, 16, ...
    
    {% for values in items|batch(4) %}
        {% for value in values %}
            <div>{{ value }}</div>
        {% endfor %}
        {% if loop.index0 is even %}
            <div class="xyz">Div 1</div>
        {% else %}
            {% if loop.index is divisible by(4) %}
                <div class="xyz">Div 3</div>        
            {% else %}
                <div class="xyz">Div 2</div>
            {% endif %}
        {% endif %}
    {% endfor %}
    

    demo


        | 1   | 2 |
    1   | 3   | 4 |
        | DIV | 1 |
    
        | 1   | 2 |
    2   | 3   | 4 |
        | DIV | 2 |
        
        | 1   | 2 |
    3   | 3   | 4 |
        | DIV | 1 | 
        
        | 1   | 2 |
    4   | 3   | 4 |
        | DIV | 3 |
        
        | 1   | 2 |
    5   | 3   | 4 |
        | DIV | 1 |
    
        | 1   | 2 |
    6   | 3   | 4 |
        | DIV | 2 |
        
        | 1   | 2 |
    7   | 3   | 4 |
        | DIV | 1 | 
        
        | 1   | 2 |
    8   | 3   | 4 |
        | DIV | 3 | 
        
        | 1   | 2 |
    9   | 3   | 4 |
        | DIV | 1 |
    
        | 1   | 2 |
    10  | 3   | 4 |
        | DIV | 2 |
        
        | 1   | 2 |
    11  | 3   | 4 |
        | DIV | 1 | 
        
        | 1   | 2 |
    12  | 3   | 4 |
        | DIV | 3 |