The Curious Case of Missing Post Tags in Eleventy
I've recently started using Eleventy for this website. Like most people who are getting started, I found an example site that did most of what I wanted and started tweaking it to my needs. One thing I saw others do that I wasn't able to do (yet) was automatically tag all files in a directory to indicate that they are posts.
A quick background about collections
In Eleventy you will eventually work with collections, which are what they say on the tin —
collections of items, be it blog posts, tags, or whatever. In my case, I have a posts
directory
that contains all the markdown files representing posts for the blog. Eleventy is smart enough to
aggregate everything I've tagged with "posts" and then I can call for those when showing a post list.
The most basic setup for tags
Here's a very basic example:
---
title: The Bark of the Aardvark
tags:
- posts
---
Since I tagged this with "posts", when I ask for the collection called "posts" it'll come along for the ride. All is good, right?
Level up — directory specific data files
I'm a developer, and therefore am inherently lazy. I want to do the least possible work to achieve as good a result as possible. I don't want to have to tag every blog post with "posts" because it takes time (albeit a miniscule amount), but more importantly, I have to remember to do it. What kind of debugging hell am I going to get myself in to the minute I forget that tag? Will my brain connect the dots that I forgot the critically important "posts" tag?
This is where directory specific data files come in handy. Since all of my post files are
in a single directory (boringly called "posts"), I can add a directory data file posts.json
to
that directory and everything in it will assume whatever I put in the file. It's not a coincidence
that the directory and the file name match — they don't have to, but for the sake of simplicity,
I set it up this way. More on your options later...
Another quick example to show what that would look like:
{
"tags": "posts"
}
With this file in place, everything in the posts directory automatically gets the tag "posts", which means I can save 0.25 seconds per blog post by not having to type out the word "posts" in the tags section. This is the epitome of optimization! /s
Here's where you can get got
The first time I tried this, I didn't understand how data cascade works in Eleventy. I thought that since I used the directory specific file that the tag would always be added. Well, it was, until I started tagging posts with other tags, like this:
---
title: The Bark of the Aardvark
tags:
- animals
- stories
---
Notice that I left out "posts" because it should be brought in from the JSON file. Sweet! BUT... What I was seeing was that The Bark of the Aardvark was no longer in my post list. It took me a second of reading the docs to realize that local data keys override global data. In other words, because I added the tags "animals" and "stories" in my post, the "posts" tag gained from the directory data file was lost.
The solution
Once I had the problem pinned down, the solution was incredibly simple. What is needed is to add
the data deep merge setting in .eleventy.js
. As per
the documentation, this will likely become the default and this whole article will be moot. In
the interim, hopefully someone finds this useful.