DEV Community

Steven Woodson
Steven Woodson

Posted on • Originally published at stevenwoodson.com on

A Step-by-Step Guide to Sorting Eleventy Global Data Files by Date

In Eleventy, there’s a lot of helpful built in methods to manage content sorting by date. But if you wanted to manage your static (or API-driven?) data files by date then you’ve got a bit of manual work to do. In this post I’m going to share two date sorting options, automated by file last modified and manually via another data property. Let’s see some code!

The Setup

Both of the following sorting options assume that you have a data folder set up in your Eleventy codebase full of files of individual records. A data collection object of objects will then be made available to you at build time.

For example, with this folder structure:

_data
└─ widgets
   │ Algorithm Ace.json
   │ Binary Buddy.json
   │ Debugging Dynamo.json
   │ Function Friend.json
   │ Loop Leader.json
   │ Statement Strategist.json
   │ Syntax Savior.json
Enter fullscreen mode Exit fullscreen mode

You’ll get something like the following collection when referencing widgets in your templates, where intro is some example data inside the individual JSON files:

{
  'Algorithm Ace': {
    intro: 'The expert in all things algorithm, helping you optimize your code like a pro.'
  },
  'Binary Buddy': {
    intro: 'The ultimate sidekick for your digital adventures, always there to convert and calculate.'
  },
  'Debugging Dynamo': {
    intro: 'Helping you solve your coding problems with lightning speed, making debugging a breeze.'
  },
  'Function Friend': {
    intro: 'A trusty organized companion whose motto is "A place for everything and everything in its place"'
  },
  'Loop Leader': {
    intro: 'The master at managing loops, ensuring your code runs smoothly and efficiently every time.'
  },
  'Statement Strategist': {
    intro: 'Fearlessly guiding you through even the toughest if/else statements'
  },
  'Syntax Savior': {
    intro: 'Never fear whether you need a color or a semicolon again!'
  }
}
Enter fullscreen mode Exit fullscreen mode

Automated Date Sorting by Last Modified

I wanted to document this one for posterity because, alas, it ended up not being the solution we wanted for the problem we were solving. But it works great if you have a need to sort by modified date, less control but more automated. Here’s how it works

Create a filter in your 11ty config file at .eleventy.js like the following.

  eleventyConfig.addFilter("sortDataByDate", (obj) => {
    const fs = require("fs");
    const directory_name = "data/members";
    const filenames = fs.readdirSync(directory_name);
    const sorted = {};

    filenames
      .map((fileName) => ({
        name: fileName,
        time: fs.statSync(`${directory_name}/${fileName}`).mtime.getTime(),
      }))
      .sort((a, b) => b.time - a.time) // Latest first, swap a & b for opposite
      .map((file) => file.name.split(".")[0])
      .forEach((name) => (sorted[name] = obj[name]));
    return sorted;
  });
Enter fullscreen mode Exit fullscreen mode

Note that the above code sorts by latest first, if you need to swap that then reverse a and b in line 12.

Manual Date Sorting by Data Property

This is going to take a bit more work, but you’ll have the most control over how the sorting happens. So if you don’t want the order of sorting to change as you change your files, this is the one for you.

First, you’ll need to add dates to the data in each file. The format is up to you, as long as it’s parsable by JavaScript. I’d recommend either a plain date like 2023-12-25 if you don’t need to get too granular, or date and time like 2023-12-25T12:30 if you also need time. You can get into seconds too, if you need.

Here’s an updated example of good ol’ Binary Buddy

{
  date: '2023-12-25T12:30',
  intro: 'The ultimate sidekick for your digital adventures, always there to convert and calculate.'
}
Enter fullscreen mode Exit fullscreen mode

And here’s a new filter to add to the Eleventy config:

  /**
   * Sort by data files `date` field
   */
  eleventyConfig.addFilter("sortDataByDate", (obj) => {
    const sorted = {};
    Object.keys(obj)
      .sort((a, b) => {
        return obj[a].date > obj[b].date ? 1 : -1;
      })
      .forEach((name) => (sorted[name] = obj[name]));
    return sorted;
  });
Enter fullscreen mode Exit fullscreen mode

Using the filtered data in your template

Regardless of whether you chose manual or automated date sorting, the resulting usage in a template is the same. Here’s an example of the for loop you’ll need, with the sorting filter applied to it:

<ul class="widgets">
{% for key, widget in widgets | sortDataByDate %}
  <li>{{ key }} - {{ widget.intro }}</li>
{% endfor %}
</ul>
Enter fullscreen mode Exit fullscreen mode

That’s it! Now that list will be sorted by the last modified date of the files within your _data/widgets folder.

Some Background

Adding this at the end here for folks that are interested in how this came about, as I realize it’s a rather interesting use case. I heard about a11y-webring.club that Eric Bailey started and – of course – jumped at the chance to get this site added to it.

To get added, you have to start a pull request adding your details to a single members.json file in the 11ty-based site code. As you can imagine, once more than one person edited that file to add their details a merge conflict ensued. So I started this discussion to bring up the idea of file-based additions instead of everyone editing one file, which led to this PR.

In working through a solution to ensure folks were added chronologically, I came up with both methods outlined in this post. We ended up going with the latter.

Have you tackled date-based data sorting another way? We’d love to hear more perspectives and insights on this!

Top comments (0)