Add div after every 3d element twig loop, modulus
You can use the batch filter instead (New in 1.12.3).
{% for date, date_info in dates|batch(3) %}
.....
.....
{% endfor %}
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>
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 %}