Well, I seem to have made it through a Jekyll and Hugo to Eleventy conversion, and come out the other side with a set of posts going back a decade. Hail plain text formats!
Eleventy has been an accessible (for me) platform to do this. What have I had to tackle?
A variety of sources
The posts collated together here cover a few years of a "personal engineering" Hugo blog I've kept internally at Catalyst, and about as many years of Jekyll blog I'd stopped updating when I joined Catalyst. Two similar (markdown-based static site generator) systems with subtly different data sets. The frontmatter for both engines was different, and I did a little juggling with perl find and replace to rearrange things. I had both categories from Jekyll and tags from Hugo, for example.
It could be tempting to perform a "migration" from Hugo and Jekyll to Eleventy, but one lovely aspect of Eleventy here was that it was flexible and fast enough for me to fix things on the fly. So I didn't need to do that.
Tags
Eleventy uses tags differently, but in a way which works for me. Specifically, all posts are members of the "post" collection, via a src/posts/posts.json
data file which sets that tag on the contents of the directory. When displaying tags for an article, that means I filter out the tag "post", such as at the top of this page.
On the front page of the site, I surfaced the tags for each post - this was mostly a lazy way for me to visually check if any posts were missing tags. (They are. I'll get to them.)
Dates
For a long time on at least one of these blogs, I was hand-entering something like ISO dates. And sometimes got them wrong, cos I forget small things. So I wrote a couple lines of filter to handle most any date that the posts would throw Eleventy's way.
eleventyConfig.addFilter("postDate", function(dateInput) {
let dateObj = DateTime.fromJSDate(dateInput);
if (dateObj.invalid) {
dateObj = DateTime.fromISO(dateInput);
}
if (dateObj.invalid) {
dateObj = DateTime.fromFormat(dateInput);
}
return dateObj.toLocaleString(DateTime.DATE_MED);
});
Syntax highlighting
Eleventy had PrismJS built in and that worked well once set up, but I had to nudge a few formats about - in my Hugo blog I'd used "cron" format which PrismJS didn't like, and so on. So, a little content mop-up required.
This isn't quite working right yet - I'm seeing things highlighted but combined into a single line on deployment. TBD.
Tailwind CSS
I tried Tailwind CSS, and I've decided it's perfectly good. I wasn't sure at first. It's a whole vocabulary I'd need to either pick up or look up to operate with, which is something. But it's produced a tidy, painless layout which I'd otherwise have probably spent ages getting approximately right.
I'm using eleventy-plugin-tailwindcss which seems to work great.
Drafts
I had posts with draft: true
set, and didn't want to drop them all on the world. I used eleventy-plugin-ignore.
Permalinks
My previous Jekyll blog had dates in the filename (posts/2023-03-06-jekyll-to-eleventy
) but not in the paths (/jekyll-to-eleventy
). I didn't want to have to handle the redirects, so I used Eleventy's per-directory JSON to rewrite paths.
In .eleventy.js
:
eleventyConfig.addFilter('stripDatePrefix', str => {
return str.replace(/^[0-9-]+/, '')
});
In src/posts/posts.json
:
{
"permalink": "/{{ page.fileSlug | stripDatePrefix }}/"
}
Gists
I'd previously used a {% gist <url> %}
and needed to convert this from Jekyll.
eleventyConfig.addShortcode("gist", function(url) {
return `<script src="${url}.js"></script>`;
});
Large media and hosting
I'm already deploying this to Gitlab Pages, easy. However ... I want to have a slightly more flexible and funcitional hosting environment. So I'll wire up a deploy over SSH/rsync from Gitlab CI.