Jon Griffith
Jon Griffith

Reputation: 183

For Loops and Jekyll: Selecting Specific Indices in a loop?

So let's say that you have a database:

Brand | Model | Serial No | Location | IP Address | Service Date | Etc...

To create column headers, I identify the first in the loop and then run another for loop for each column in the set using field[0]. Then, I run another for loop on the data and the field[1] data from left to right.

This builds the table nicely. How do I run through the field[1] for loop and selectively choose each column? Let's say for one page I want to show Brand | Model | Serial NO, but on another page I want to include only Brand | Model | IP Address.

Until now, the only way I've managed to do this is to put a forloop.index condition inside of the field for loops to look for {% if forloop.index == 1 and forloop.index == 3 %} as an example, etc. This doesn't seem efficient.

<table>

{% for item in site.data.equipment %}

  {% if forloop.first == true %}

  <tr>
   {% for field in item %}
    <th>{{ field[0] }}</th>
   {% endfor %}
  </tr>

  {% endif %}

  {% for item in site.data.equipment %}

  <tr>
    <td>{{ field[1] }}</td>
  </tr>

  {% endfor %}

{% endfor %}
</table>

Upvotes: 0

Views: 709

Answers (1)

David Jacquel
David Jacquel

Reputation: 52809

You can identify a column by its index :

Brand | Model | Serial No | Location | IP Address
1       2       3           4          5

You can then select printed columns based on a simple array. In this example it is stored in page front matter, but can also come front _config.yml.

---
# page front matter
# ....
displayCol: [1,2,4]
---
{% assign equipment = site.data.equipment %}

<table>
{% for item in equipment %}
  {% if forloop.first == true %}
    <tr>
    {% for field in item %}
      {% if page.displayCol contains forloop.index %}
      <th>{{ field[0] }}</th>
      {% endif %}
    {% endfor %}
    </tr>
  {% endif %}

  <tr>
  {% for field in item %}
    {% if page.displayCol contains forloop.index %}
    <td>{{ field[1] }}</td>
    {% endif %}
  {% endfor %}
  </tr>

{% endfor %}
</table>

edit :

You can also use a selection array from page logic like {% assign displayCol = "1,2,4" | split: "," %} (creating an array from a string, which is the only way to create an array inside page code), referenced as displayCol instead of page.displayCol.

The problem is that it creates an array of strings : {% assign displayCol = "1,2,4" | split: "," %} => ["1", "2", "4"]. And it will not be posible to test forloop.index(integer) presence in an array of strings.

The solution will be to cast forloop.index to a string with {% assign indexToStr = forloop.index | append:"" %}

Resulting code will be :

{% assign equipment = site.data.equipment %}
{% comment %}Here is the setup for displayed columns{% endcomment %}
{% assign displayCol = "1,2,4" | split: "," %}

<table>
{% for item in equipment %}
  {% if forloop.first == true %}
    <tr>
    {% for field in item %}
      {% assign indexToStr = forloop.index | append: "" %}
      {% if displayCol contains indexToStr %}
      <th>{{ field[0] }}</th>
      {% endif %}
    {% endfor %}
    </tr>
  {% endif %}

  <tr>
  {% for field in item %}
    {% assign indexToStr = forloop.index | append: "" %}
    {% if displayCol contains indexToStr %}
    <td>{{ field[1] }}</td>
    {% endif %}
  {% endfor %}
  </tr>

{% endfor %}
</table>

Upvotes: 3

Related Questions