Right here, right now
2024-01-07
One day while reading a blog post I noticed the blog had a "Now" page, where the author briefly described what they were up to at the moment. Unfortunately, I can't recall the specific blog, but it did link to Nownownow.com, which is a page by Derek Sivers promoting the concept of the Now page. Two things stuck with me: Derek seemed to be a very interesting person, and as someone with periodic "flavor of the week"-style obsessions, the Now page concept was very appealing to me.
Derek compares the Now page to an About page (albeit a less static one), an auxiliary page with an easy URL that tells visitors something about the author. I used to have an About page, but as part of the rewrite of this blog, I turned it into a section on the homepage instead. This eliminated the need for any menu or other navigation elements, and to avoid adding any back solely for a Now page, I decided to include that too as a section on the homepage.
An unsatisfactionary attempt
I could have simply added a paragraph to the homepage and updated that as needed, but my mind rarely lets me get away that easily. I knew I wanted to keep a record of the history of my Now content one way or the other, perhaps to list it as a timeline of sorts in the future.
My first attempt was having the content as a separate file, rendered as part of the homepage using the Eleventy Render plugin. The plugin is included with Eleventy, and can be activated in the .eleventy.js
:
const { EleventyRenderPlugin } = require("@11ty/eleventy");
module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(EleventyRenderPlugin);
// Further configuration ...
};
With the plugin activated, you can render any Eleventy template from any other template like this:
<article>
{% renderFile './_includes/now.md' %}
</article>
This worked fine, and I got an automatic file history in Git. However, that isn't the most accessible place if I would like to list previous entries on the site in the future.
Round 2
One night as I was falling asleep I realized that my Now content should of course be treated like any other content in Eleventy. This would probably have been obvious from the beginning if I had a little bit more Eleventy experience, but it took some time for the penny to drop.
Content
Eleventy is highly flexible regarding content. You can have different types of content for different purposes, located anywhere in the file structure, and you have a lot of control over the behavior it all.
For my Now content, I had a fairly clear idea of what I wanted:
- A list of tiny Markdown files in a separate directory, to keep things tidy.
- An Eleventy collection of that content, sorted by date.
- Prevent the content from being rendered into individual pages.
- Keep the files clear of any frontmatter or other metadata.
I created a directory called now
, and added my first post called 2024-01-04.md
, for lack of a better name. Even though I didn't want any metadata in the files, I still needed to specify at least two pieces of information for each of them: a tag to keep the content organized in a collection and a date to have them sorted correctly.
Automatic tagging
Since the Now posts live in a directory of their own, I knew I could utilize the Data cascade in Eleventy, and add a directory data file that applies common attributes to all files in that directory. Directory data files should be located inside their respective directories and named following the pattern [directory name].11tydata.[format]
. Following this convention, I created a file named now.11tydata.json
in my now
directory, containing a single property:
{
"tags": "now"
}
This little snippet assigns the now
tag to all posts in the now
directory. As a resuly, they'll be accessible as collections.now
in Eleventy.
Excluding content from rendering
With a small addition to the directory data file, I could also disable the content from being rendered into individual pages:
{
"tags": "now",
"permalink": false
}
The permalink
property can be set to a pattern telling Eleventy where to put the pages rendered from each post. Setting it to false
means no rendering will take place at all.
Dates
As mentioned, I also wanted to set the date of each post somehow, both for my historical records and to be able to display the latest post on the homepage. I was prepared to implement some kind of computed property setting the date based on the filename. To have something to work with, I added a couple of more posts to the now
directory. To my surprise, they automatically appeared in the correct order. Was this just a fluke, or some clever feature in Eleventy? A bit of both, it turns out!
The Content Dates section of the Eleventy docs held the answer. Eleventy goes to great lengths to find a date for each post. You can specify one in different ways, but ...
If a date key is omitted from the file, we then look for a YYYY-MM-DD format anywhere in the file path (even folders).
Clearly a very clever feature in Eleventy, but I also got lucky naming my files according to the one true date format, and that Eleventy looks for this very format as part of the file path. What I expected to be the trickiest part of this setup turned out to work straight out of the box. Sweet!
Rendering
With the now
collection sorted (*badum-tss*), all I had to do was to include the latest post from it on my homepage. I already do this with my latest post post, so this part was easy:
{% set now = collections.now | last %}
<article>
<h2>Right now</h2>
{{ now.content | safe }}
</article>
The latest post in the collection is picked out using the last
filter. The content of the post can then be accessed using the now.content
property. The safe
filter inserts the content of the post as-is, without any escaping of special characters.
The same thing can be written as a shorter but less readable oneliner:
{{ (collections.now | last).content | safe }}
Conclusion
The solution to my problem turned out to be quite straightforward, perhaps even too much so for a tutorial like this. However, I learned several things about Eleventy in the process, and I hope others will too.
My main takeaways are:
- Eleventy is built to deal with content, and large amounts of it too. Any time you're working with a series of content, even if you just want to use something like the latest piece of it, consider using tags and the resulting collections before exploring other alternatives.
- The Data cascade in Eleventy is both flexible and powerful, and directory data files are a convenient way to avoid repetition of metadata for content within a directory. In my case, leaving out the entire frontmatter section from my content files felt like a big win.
- It's pleasing to see all the ways Eleventy tries to find a date for each piece of content, including inspecting the file path, and extra pleasing to see it's specifically looking for ISO 8601 dates.
Getting to know Eleventy has been a true delight, and this little project only strengthens my positive impressions of it. For those who want to know more, I've collected all my Eleventy-related posts for easy reference. I encourage anyone embarking on a web project to consider Eleventy. It's flexibility and user-friendlyness makes it a joy to work with!