The Tale of a Migration
This is a longer one than usual, so bear with me.
In June 2020 I changed the way in which I publish this site. Out went the Jekyll static site generator and in came handcrafted HTML5 and CSS.
To be honest, while I was excited by the thought of migrating The Plain Text Project to HTML5 and CSS, I was also a little hesitant. I dreaded the amount of work that I was facing to complete the job. Then again, that pile of work would only get bigger the longer I waited.
As it turned out, there wasn’t as much work as I thought there would be. Since the files that made up the site were formatted with Markdown, they were easy to convert to HTML.
I was also able to automate a lot of the conversion process. Most of the fiddly, manual work was a set of simple tasks that only took a few seconds to complete.
Here’s a look of how I moved this site from being published with Jekyll to hand-coded HTML5 and CSS.
Why the Change?
In the months leading up to the migration, I’d been thinking about something I call the DIY web. A web harking back to the 1990s, one made up of sites hewn by hand in text editors. A web with few frills. A web that doesn’t rely on technologies other than a good old fashioned server and a web browser. A web that’s easy to maintain.
I also wanted to make this site a bit more portable. It’s currently hosted with GitLab Pages, but I might decide to move the site elsewhere one day. Plus, I don't have to worry about any of Jekyll's dependencies breaking and spending time I didn't have trying to fix Jekyll's plumbing. Yes, that happened a couple or three times.
The first thing I did was find a Cascading Style Sheet (CSS) file to use with the site. I could have written one of my own, but my CSS is rusty and there are gaps in my knowledge. Gaps I really didn’t (and don't) have the time or inclination to fill. On top of that, I don't have much visual sense.
Instead, I looked at about half a dozen CSS files released with free/open source licenses and settled on MVP.css. Why MVP.css? I was playing with it as part of a side project at the (now former) Day JobTM and liked how easy MVP was to use. I did modify the file to narrow the page, change the fonts, and to style a few other elements. I also had to tweak those changes a few times as I migrated the site because of little inconsistencies that crept in and things I just didn’t like all that much.
Starting at the Top
Next, I looked at the top level pages — the landing page, the about page, and that like. I figured those would be the easiest to convert. Transforming those pages from Markdown into HTML helped me refine the technique for converting the articles I’d published on the site to HTML as well. More on that soon.
Before I could do the conversion, I needed to figure out what elements would go between the
</head> tags in the HTML files. I also needed to find a way to insert the navigation block at the top of each page and the licensing information at the bottom of the pages.
I could have copied and pasted all of that into the individual files, but that would have been a lot of work — especially with the articles. Instead, I turned to Pandoc.
One of the many nifty features of Pandoc is a set of options to include the contents of another file into a document that you’re converting to HTML or LaTeX. Those options dropped the HTML code I needed where I needed it.
I created three text files — each containing the components to add to the page header, the navigation block, and the footer. Here’s the command I ran to do that:
pandoc -t html5 -s $1.md -H Collateral/_includes/page-head.txt -B Collateral/_includes/navigation.txt -A Collateral/_includes/footer.txt -o $1.html
That command tells Pandoc to:
- Generate a full HTML5 page from a Markdown file
- Insert the contents of the file page-head.txt just before the
- Add the contents of the file navigation.txt right after the
- Include the contents of the file footer.txt just before the
Recreating the Articles Page
The page I worried about was the Articles page. Jekyll automatically built the page when I updated the site with new articles. That left me in a minor bind since I had to rebuild the Articles page from scratch. I didn’t do it by hand (I’m not that much of a masochist!). Instead, I took the HTML code from the (at the time) latest version published with Jekyll.
As the page was getting a bit long, I added the option to expand and collapse the articles published during a particular year using the HTML5
<details> tag. Here's the result:
Now, I just add a link to new articles as I need to. Luckily, I only publish articles two or three times a month, so that’s not an arduous task.
Converting the Articles
When I did the migration, I had over 100 articles to convert from Markdown to HTML. That had to be done one file at a time. Why? Again, I relied on Jekyll to add elements to each article, like the byline and the date on which it was published. Also, there are some contributed articles on the site that use a different license than the one I use. So, I needed to change things by hand.
Remember those files I created to insert content into parts of a page? They were crafted for the pages at the top level of the site. Each article was four directory levels down from the top, so I had to edit the include files to ensure that all links pointed to the right place.
On top of that, I modified the command I used to convert the top-level pages and encapsulated that into a very simple, very lame script. I just ran the script and the conversion happened like magic.
With that out of the way, I still needed to:
- Insert the byline and publication date below the article’s title
target="_blank"to links to open them in a new browser tab
- Rename the files and put them into sub folders
- Resize images as needed
The second last point sounds a bit strange if you’re not used to working with a static site generator. With Jekyll, you can give your blog posts a name like
2020-11-05-migration.md. When Jekyll builds a blog, it adds the date in the file name to the body of your post. It also names the resulting HTML file with slug at the end of the file name — with the example a few sentences back, the resulting file is
On the published site, that file goes into a folder structure that looks something like this:
I did the renaming and moving by hand. I wouldn't doubt that there's a way to automate that, but I don’t know what it is.
As I mentioned a while back, all articles on the site are now under the articles/ subfolder. That messes up some peoples' bookmarks, and again I apologize for that. If I knew how to create a web server URL rewrite rule (as someone suggested) and knew that it worked with GitLab Pages, I'd do that.
Fixing the RSS Feed
Ah, the site’s RSS feed … In the past, a Jekyll plugin created the feed automatically. But the plugin didn’t always do its job. The feed was balky. I investigated a few online services that create RSS feeds, but none of them worked to my satisfaction.
One reader of The Plain Text Project pointed me to an article explaining how to build an RSS feed by hand. Using that article, looking at the feeds for sites I subscribe to, and through trial and a lot of error, I managed to handcraft a working (well, I hope it's working!) feed. Even though I'm editing it by hand, the feed is fairly easy to update. Even when I mess it up (as I do every so often) ...
Moving this site from Jekyll to HTML5 and CSS only took about four or five hours spaced across a few evenings. The migration went faster than I thought it would. Being able to automate chunks of the process helped. A lot.
Now, when I publish this site to GitLab Pages, it takes less than 30 seconds to deploy. Compare that to the three minutes and up that it took when using Jekyll.
Admittedly, maintaining The Plain Text Project now requires a little more manual work, but that’s nothing too gruelling. I’ve automated a lot of that work, which makes those tasks quicker and easier.
I’m not sure if any or all of the fives of you who read The Plain Text Project like the new look. I do. I can’t say I’ll never go back to using a static site generator. But right now, embracing the DIY web works for me.
* * *