7

Hi so i have this twig loop, and what i need to to is after every 3rd element to add some html to close div row and open new one.

I tried with various snippets from this website but no luck with any one of them

<div class="row">
    {% for date, date_info in dates %}
        <div class="col-sm-4">
            <div class="event-box">
                {% for category in date_info.events %}
                    {% for event in category %}
                        <div class="event-header">
                            {% if event.get_runtime( 'content_img_url' ) is empty %}
                                {{ event | avatar( [
                                'post_thumbnail',
                                'location_avatar',
                                'category_avatar'
                                ]) | raw }}
                            {% endif %}
                            <div class="event-date">
                                {{ date | month }}
                                {{ date | day }}
                            </div>
                            <div class="event-footer">
                                <h3>{{ event.get_runtime( 'filtered_title' ) | raw }}</h3>
                                <div class="event-time">
                                    {{ event | timespan( 'short' ) | raw }}...
                                </div>
                                <div class="event-content"> {{ event.get_runtime( 'filtered_content' ) | slice(0,200) | raw }}</div>

                                <a  class="btn btn-success" href="{{ event.get_runtime( 'instance_permalink' ) | e('html_attr') }}">
                                    {{ text_read_more }}
                                </a>
                            </div>
                        </div>
                    {% endfor %} {# event in category #}
                {% endfor %} {# category in date_info.events #}
            </div>
        </div>
    {% endfor %} {# date, date_info in dates #}
</div>
RevanProdigalKnight
  • 1,316
  • 1
  • 14
  • 23
Alex
  • 374
  • 1
  • 4
  • 13

4 Answers4

34

You can use the batch filter instead (New in 1.12.3).

{% for date, date_info in dates|batch(3) %}
   .....
   .....
{% endfor %}
dwenaus
  • 3,206
  • 2
  • 27
  • 27
albertski
  • 2,428
  • 1
  • 25
  • 44
19

I think this is better solution:

{% for date, date_info in dates %}
   {% if loop.first %}
      <div class="row"> {# open row #}
   {% endif %}


       {# your code here #}


    {% if loop.index % 3 == 0 %}
        </div><div class="row"> {# after 3 iterates close row and open new #}
    {% endif %}                
    {% if loop.last %}
        </div> {# close last row #}
    {% endif %}
{% endfor %}
fafii
  • 191
  • 2
  • 2
16

Got it working with {% if loop.index is divisible by(3) and not loop.last %}.

Here is my full working code example :

<div class="row">

    {% for date, date_info in dates %}
        <div class="col-sm-4">
            <div class="event-box">
                {% for category in date_info.events %}
                    {% for event in category %}
                        <div class="event-header">
                            {% if event.get_runtime( 'content_img_url' ) is empty %}
                                {{ event | avatar( [
                                'post_thumbnail',
                                'location_avatar',
                                'category_avatar'
                                ]) | raw }}
                            {% endif %}
                            <div class="event-date">
                                {{ date | month }}
                                {{ date | day }}
                            </div>
                            <div class="event-footer">
                                <h3>{{ event.get_runtime( 'filtered_title' ) | raw }}</h3>

                                <div class="event-time">
                                    {{ event | timespan( 'short' ) | raw }}...
                                </div>
                                <div class="event-content"> {{ event.get_runtime( 'filtered_content' ) | slice(0,200) | raw }}</div>

                                <a class="btn btn-success"
                                   href="{{ event.get_runtime( 'instance_permalink' ) | e('html_attr') }}">
                                    {{ text_read_more }}
                                </a>
                            </div>
                        </div>
                    {% endfor %} {# event in category #}
                {% endfor %} {# category in date_info.events #}
            </div>
        </div>

        {% if loop.index is divisibleby(3) and not loop.last %}
        </div>

        <div class="row">

        {% endif %}

    {% endfor %} {# date, date_info in dates #}

</div>
shakaran
  • 10,612
  • 2
  • 29
  • 46
Alex
  • 374
  • 1
  • 4
  • 13
  • 1
    I think this is not totally correct. If you have 3 items this will let the "
    " open. You should close the div outside of the loop and add "and not loop.last" in the "if condition" to prevent this.
    – progzy Feb 09 '16 at 11:49
7

In reading this doc : http://twig.sensiolabs.org/doc/tags/for.html#the-loop-variable

I'll try this kind of code :

{% for date, date_info in dates %}
   {% if  loop.index % 3 == 0 %}
       {# put your code to close your div #}
   {% endif %}
{% endfor %}
BENARD Patrick
  • 30,363
  • 16
  • 99
  • 105