6

I try to write a row in which there are two columns:

<div class="row">
   <div class="block_txt"></div>
   <div class="block_txt"></div>
</div>
<div class="row">
   <div class="block_txt"></div>
   <div class="block_txt"></div>
</div>
{# and so on and so on #}

Now maybe there is only one block_txt div at the end so I try to wrap the row tag in a devisibleby conditional to only write the row tag every second time, or at the end. It looks like this:

{% for entry in entriesInYear %}
   {% if loop.index is divisibleby(2) or loop.first %}<div class="row">{% endif %}
      <div class="block_txt">This gets repeated n times</div>
   {% if loop.index is divisibleby(2) or loop.last  %}</div>{% endif %}
{% endfor %}

But that doesn't work the way I want. Every third block_txt isn't wrapped in a row. How do I have to math this? Or is there a better way to write the whole piece?

13

Instead of using the divisibleby-function you can use the batch-filter:

{% for row in entriesInYear|batch(2) %}
<div class="row">
    {% for entry in row %}
        <div class="block_txt"></div>
    {% endfor %}
</div>
{% endfor %}

If you have 3 entries in entriesInYear this code would output:

<div class="row">
   <div class="block_txt"></div>
   <div class="block_txt"></div>
</div>
<div class="row">
   <div class="block_txt"></div>
</div>
  • This is flippin awesome! – Florian Nov 18 '14 at 10:24
  • Very neat trick. Worked perfectly! – Anna_MediaGirl Sep 17 '15 at 16:32
10

If you wish to use divisibleby to solve this problem, the key is in how you use the loop.index and loop.index0 variables.

  • loop.index counts the iterations in your loop starting with the number 1
  • loop.index0 counts the iterations in your loop starting with the number 0

You can test this with an odd number of items using the range function:

{# Loop 3 times  #}
{% for i in 1..3 %}

  {# If index0 is divisible by 2, output the starting row #}
  {% if loop.index0 is divisible by(2) %}
    <div class="row">
  {% endif %}

    {# Output the content #}
    <div class="block_txt"></div>

  {# If index is divisible by 2, output the ending row, and
     if it is the last loop, make sure we close the open row regardless #}
  {% if loop.index is divisible by(2) or loop.last %}
    </div>
  {% endif %}

{% endfor %}

And will get your desired output and ensure your last row div element gets closed:

<div class="row">
    <div class="block_txt"></div>
    <div class="block_txt"></div>
</div>
<div class="row">       
    <div class="block_txt"></div>
</div>

You can read more on the Twig loop variable and the Twig range function in the Twig docs.

For your use case, you can then just update the range function to use the variable you need to loop through:

{% for entry in entriesInYear %}

  {% if loop.index0 is divisible by(2) %}
    <div class="row">
  {% endif %}

    <div class="block_txt"></div>

  {% if loop.index is divisible by(2) or loop.last %}
    </div>
  {% endif %}

{% endfor %}
  • 3
    Thanks for the input. I changed to the batch filter, because the code is much smaller. But the learning effect of posts like this is still big :) – KSPR Jun 26 '14 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.