Jekyll Casts - Looping in Liquid
<!--
In Liquid you often need to loop over arrays. In this tutorial taking an in-depth look at all the options available to us when we’re looping.
On our Bakery Store site we have cupcake.html which lists all the cupcakes available.
-->
---
layout: page
title: Muffins
---
<h1>Our cupcakes</h1>
<div class="cupcakes">
{% for cupcake in site.cupcakes %}
<div class="cupcake">
<div class="image">
<img src="{{ cupcake.image_path }}" alt="{{ cupcake.type }}" />
</div>
<h2>{{ cupcake.type }}</h2>
<p>{{ cupcake.description }}</p>
</div>
{% endfor %}
</div>
<!--
Cupcakes
First we’ll add an image filter in CSS to make all the images black and white.
-->
<img src="{{ cupcake.image_path }}" alt="{{ cupcake.type }}" style="-webkit-filter: grayscale(100%)" />
<!--
Black and white cupcakes
Let’s change the image filter for each image. We’ll make the first image black and white, the second sepia, the third inverted and then cycle through those options for the rest of the images. To do this we’ll use a cycle which has multiple values it iterates over each time it’s called.
-->
<img src="{{ cupcake.image_path }}" alt="{{ cupcake.type }}" style="-webkit-filter: {% cycle "grayscale", "sepia", "invert" %}(100%)" />
<!--
Cycle Cupcakes
Next we’ll number the cupcakes. We can access the current iteration of the loop using forloop.index.
-->
<h2>{{ forloop.index }}. {{ cupcake.type }}</h2>
<!--
Cupcakes Index
We can make the 0 indexed if we use forloop.index0.
-->
<h2>{{ forloop.index0 }}. {{ cupcake.type }}</h2>
<!--
Cupcakes Index0
The next thing we’ll do is change the first and last cupcakes so the title is white text on a black background. We can check it’s the first or last item in the loop using forloop.first and forloop.last.
-->
<h2
{% if forloop.first or forloop.last %}
style="background: black; color: white;"
{% endif %}
>{{ forloop.index0 }}. {{ cupcake.type }}</h2>
<!--
Cupcakes First
If we wanted to change this to the last three items instead of the first and the last we could use forloop.rindex. rindex gives us how many iterations are left in the loop. So on the first iteration the forloop.rindex will be six, on the second it would be five and on the last it would be one. We can also use forloop.rindex0 to have a zero indexed number.
-->
<h2
{% if forloop.rindex <= 3 %}
style="background: black; color: white;"
{% endif %}
>{{ forloop.index0 }}. {{ cupcake.type }}</h2>
<!--
Cupcakes rindex
When you hover of a heading on the cupcakes page, let’s make it popup with the total number of cupcakes available. I could get the size from the collection like this site.cupcakes.size or we could get it from the forloop like this forloop.length.
-->
<h2
{% if forloop.rindex <= 3 %}
style="background: black; color: white;"
{% endif %}
title="{{ forloop.length }} cupcakes"
>{{ forloop.index0 }}. {{ cupcake.type }}</h2>
<!--
Cupcakes title
We can use a continue to skip straight to the next item in the loop. So in this example we’ve skipped over the Lemon cupcake.
-->
{% for cupcake in site.cupcakes %}
{% if cupcake.type == "Lemon" %}
{% continue %}
{% endif %}
<div class="cupcake">
<div class="image">
<img src="{{ cupcake.image_path }}" alt="{{ cupcake.type }}"
style="-webkit-filter: {% cycle "grayscale", "sepia", "invert" %}(100%)"
/>
</div>
<h2
{% if forloop.rindex <= 3 %}
style="background: black; color: white;"
{% endif %}
title="{{ forloop.length }} cupcakes"
>{{ forloop.index0 }}. {{ cupcake.type }}</h2>
<p>{{ cupcake.description }}</p>
</div>
{% endfor %}
<!--
Cupcakes continue
We can use a break to exit the loop. So in this example we’re dropping out of the loop when it gets to the Lemon cupcake.
-->
{% for cupcake in site.cupcakes %}
{% if cupcake.type == "Lemon" %}
{% break %}
{% endif %}
<div class="cupcake">
<div class="image">
<img src="{{ cupcake.image_path }}" alt="{{ cupcake.type }}"
style="-webkit-filter: {% cycle "grayscale", "sepia", "invert" %}(100%)"
/>
</div>
<h2
{% if forloop.rindex <= 3 %}
style="background: black; color: white;"
{% endif %}
title="{{ forloop.length }} cupcakes"
>{{ forloop.index0 }}. {{ cupcake.type }}</h2>
<p>{{ cupcake.description }}</p>
</div>
{% endfor %}
<!--
Cupcakes break
Let’s get rid of the break statement and try reversing the order of the loop. We can do this by passing reversed to the for loop.
-->
{% for cupcake in site.cupcakes reversed %}
<!--
Cupcakes reversed
We can add a limit to a show maximum of three cupcakes and an offset which skips over the first x number of cupcakes.
-->
{% for cupcake in site.cupcakes reversed limit: 3 offset: 3 %}
<!--
Cupcakes offset
You might need to handle the case where your array is empty. In this example we’ll create an empty flavours array, then we’ll loop over that array and specify an else which is the case where the array is empty.
-->
---
layout: page
title: Muffins
flavours: []
---
{% for flavour in page.flavours %}
{{ flavour }}
{% else %}
<h3>There are no flavours</h3>
{% endfor %}