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
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!'
}
}
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;
});
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.'
}
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;
});
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>
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)