How to sort global data in a template loop with Eleventy?

37 views Asked by At

I have created an Eleventy site with liquid templates and I have a folder full of individual .json files like this

├─ src
│  ├─ _data
│  │  ├─ site.json
│  │  ├─ books
│  │  |  ├─ my-first-book.json
│  │  |  ├─ my-second-book.json
│  │  |  ├─ my-third-book.json

I want to loop through these in a template, which I can do like this

{% for book in books %}
  <a href="{{ '/books/' | url }}{{ book[1].title | slugify | url }}">
    <img src="{{ book[1].coverImageUrl | url }}" alt="{{book[1].title}}" />
  </a>
{% endfor %}

This works, but I have two issues here:

  1. I need to be able to specify that I want the data sorted by a property in the JSON data. I have tried making a eleventyConfig.addFilter('sortByDate', ...) and then using {% for book in books | sortByDate %} but the code in the filter didn't even run at all.
  2. I need to be able to get to the data without using book[1] which is not great. I have seen examples where I could do {% for key,val in books %} but that throws an error illegal tag
1

There are 1 answers

0
Ross On

For 1, Liquid could be ignoring that filter when used on the for tag. Try assigning it prior to the loop.

For 2, we'd need to see the data in each file to see if it can be avoided, but you could just assign again to avoid multiple indexed references.

Here's your code with both suggestions applied:

{% assign sorted = books | sortByDate %}

{% for tuple in sorted %}
  {% assign book = tuple[1] %}

  <a href="{{ '/books/' | url }}{{ book.title | slugify | url }}">
    <img src="{{ book.coverImageUrl | url }}" alt="{{ book.title }}" />
  </a>
{% endfor %}