Jekyll automatically processing rows

1k views Asked by At

I want to filter out from site.pages all pages with a given YAML frontmatter type 'project'.

To do this I've done this:

{% sorted_for page in site.pages sort_by:title %}                       
{% if page.type == 'project' %}
do something
{% endif %}
{% endfor %}

This uses the sorted_for plugin. What I want to do now, however is to arrange these in css rows of four.

<div class="row">
<div class="span3">{{ page1.title }}</div>
<div class="span3">{{ page2.title }}</div>
<div class="span3">{{ page3.title }}</div>
<div class="span3">{{ pagen.title }}</div>
</div>
...

And so forth, until the rows run out. How can I access the information I need to do this? Unfortunately the for loop iterator number will be wrong, as it will also tick through the non-project pages. Is there a clean way to implement this?

1

There are 1 answers

0
Christian Specht On BEST ANSWER

Note:
I couldn't get the sorted_for plugin to work in my machine, so I tested my solution with a regular for instead.

Step 1

As you can't use forloop.index because you're filtering out some pages, you need to count the loops by yourself, by writing to a variable with assign.

The following code will just list your pages with a correct loop iterator (by counting just the pages that are actually listed):

{% assign loopindex = 0 %}
{% for page in site.pages %}                       
  {% if page.type == 'project' %}
    {% assign loopindex = loopindex | plus: 1 %}
    <div class="span3">{{ loopindex }} {{ page.title }}</div>
  {% endif %}
{% endfor %}

Step 2

You need to display <div class="row"> with every first row and </div> with every fourth row.

To find the first and fourth rows, you can use modulo:

{% assign loopindex = 0 %}
{% for page in site.pages %}                       
  {% if page.type == 'project' %}
    {% assign loopindex = loopindex | plus: 1 %}
    {% assign rowfinder = loopindex | modulo: 4 %}
    <div class="span3">{{ loopindex }} {{ rowfinder }} {{ page.title }}</div>
  {% endif %}
{% endfor %}

rowfinder will always repeat the sequence 1, 2, 3, 0.

Step 3:

So you display <div class="row"> when rowfinder is 1, and </div> when rowfinder is 0:

{% assign loopindex = 0 %}
{% for page in site.pages %}                       
  {% if page.type == 'project' %}
    {% assign loopindex = loopindex | plus: 1 %}
    {% assign rowfinder = loopindex | modulo: 4 %}
    {% if rowfinder == 1 %}
      <div class="row">
      <div class="span3">{{ page.title }}</div>
    {% elsif rowfinder == 0 %}
      <div class="span3">{{ page.title }}</div>
      </div>
    {% else %}
      <div class="span3">{{ page.title }}</div>
    {% endif %}
  {% endif %}
{% endfor %}

Step 4:

Now there's only one small thing left: when the number of pages is not a multiple of 4, there's a </div> missing at the end.

When the number of pages is a multiple of 4, the last value of rowfinder will be 0.
So we just need to display the </div> when the value of rowfinder is anything else but 0.
So just put this after the for loop:

{% if rowfinder != 0 %}
      </div>
{% endif %}

...and that's it!