It had to happen eventually, I suppose.
I've had blogs before, but they've always been on external hosting services and quickly abandoned. With this one I've rectified the former issue. We'll see about the latter.
I don't expect a lot of people will read this, so why bother with a blog in 2024?
Writing forces me to organise my thoughts. Additionally, publishing a blog entry is small act of rebellion against that self-sabotaging force of procastination that doesn't want to release or finish anything because it's not "good enough".
In terms of technology, I had a small list of requirements. It had to be static (I can't be bothered to pay for and maintain a server at the moment), I wanted to keep my existing (so called) design, and it had to be simple. I'm happy for the blog itself to be a reverse chronological list of posts.
If you want to comment, my about page has my contact details.
First thought was to write the entries myself. I don't mind writing HTML by hand, and this site was a couple of HTML files, so what's a few more? Short term, I want to add RSS support -- so having titles and dates without having to parse HTML seemed like a good idea. Long term, I don't want to bake the (so called) design into entries and have to migrate a bunch of HTML files. Basically I'm trying to organise my life in such a way as to minimize parsing HTML.
The next idea was to do it myself. Copy and concatenate some files, parse a little markdown -- no problem, right? I even went so far as writing some code. It became clear, however, that this lead down two paths:
With that revelation, I decided to do the sensible thing and use an existing generator.
Hugo was the first that I thought of. We use it at work, so I'm fairly familiar with it. The wrinkle I ran into was that I wanted to keep my existing (so called) design and not just pull down a theme. Hugo themes seem quite powerful, so I have no doubt that with enough patience I could have sat down and made it work. But like most side projects, this has to fit in that limited amount of time where I'm not working but still have energy to work on computer stuff. A certain point through the Hugo docs I decided to look at an alternative. Something simpler.
11ty's slogan is Eleventy is a simpler static site generator, so in terms of marketing they're right on the money.
Taking my existing site and running npx @11ty/eleventy
gets those HTML pages into the generated site. This was one of the things that sold me on it. However, those HTML files refer to CSS files and favicons. To get those into the generated site required the creation of a config file, eleventy.config.js
.
export default async function(eleventyConfig) {
eleventyConfig.addPassthroughCopy("sakura.css")
eleventyConfig.addPassthroughCopy("favicon.ico")
eleventyConfig.addPassthroughCopy("favicon-16x16.png")
eleventyConfig.addPassthroughCopy("favicon-32x32.png")
eleventyConfig.addPassthroughCopy("snake")
eleventyConfig.addPassthroughCopy("jsrogue")
}
As you can see, the Eleventy config file is a JavaScript file. Those last two entries are folders (see my projects page) with old JavaScript/HTML games of mine.
By default if you have the file banana.html
, Eleventy will place it in banana/index.html
(as an exception, this doesn't apply to a file named index.html
). This is a sane default, as it lets you have the URI example.com/banana
and not expose implementation details of your site. But cool URIs don't change, and I already had a page that ended in .html
, so I wanted to not break that URL.
This was easily achieved by adding permalink
to the front matter before the HTML file proper.
---
permalink: "projects.html"
---
<!DOCTYPE html>
Creating the contents of the blog posts themselves was easy enough. Stick some markdown files in a folder named posts
(the name here is arbitrary). In the per post front matter, I added a title and date.
---
title: First Blog Entry
date: 2024-11-14
---
In the same folder, I created a file posts.json
which has some front matter that applies to all the files in the folder.
{
"layout": "blogentry.html",
"tags": "post"
}
The layout
refers to the HTML file that will be wrapped around the HTML generated from the markdown. Placing blogentry.html
in a _includes
folder. I won't reproduce the entire thing here, but in the <body>
element:
<h2>{{ title }}
<small>{{ page.date | readableDate }}</small></h2>
{{ content }}
The double curly braces are macros that are replaced depending on the page being generated. The{{ page.date | readableDate }}
macro requires a little explanation. If we drop the filter from the end, this is what the title looks like.
Not ideal. Constructing a filter to turn the JS Date into something a little prettier is fairly easy. It can be added to the config file:
eleventyConfig.addFilter("readableDate", dateObj => {
return dateObj.toISOString().split('T')[0];
});
In case the (so called) design of my site has changed, this is what {{ page.date | readableDate }}
looks like:
The last thing to do is to create an index. The interesting part is more simple macro code:
{%- for post in collections.post reversed -%}
<a href="{{ post.url }}">{{ post.data.title }}</a> <em><small>({{ post.date | readableDate }})</small></em><br>
{%- endfor -%}
This is why the posts.json
needed the post
tag -- so we could refer to all the blog posts. The reversed
gets us reverse chronological order. At time of writing there's just the one post, but it seems to work.
That's enough for now, I think. If you made it all the way through this, thank you for reading! My next task is to get an RSS feed up and running. If you have any comments, see the about page for ways to get in touch.