From Wordpress to Windrunner SSG: Making my own static site generator
There’s an emptiness to the days after an achievement. As the elation of realising a goal fades — always too quickly — it leaves behind a vacuum. Where once there was a guiding star, a shining goal to navigate by, now there is nothing.
"And now what?"
You might find yourself asking.
I took that question as a call to write down everything I could recall about what I'd been doing leading up to the achievement and subsequent emptiness. This post is the result of that. My unabridged recounting of why I decided to drop Wordpress and how I replaced it with my own custom static site generator, Windrunner SSG.
The backstory
Through numerous launches and relaunches, there has been one mainstay throughout the two decades of this website's existence: Wordpress has been the engine that powered the site. Originally dedicated blogging software, Wordpress soon developed into a complete CMS (Content Management System) and eventually a full-fledged site builder.
All the while, I never questioned it being the obvious choice when I reached for a tool to build a website of any kind. With the relaunch of this blog a year back, however, things began to change. With my forays into the world of the Indieweb, I began to question every aspect of my relationship with technology. Or was it the other way around? Did my reflections on technology lead me to the Indieweb?
I honestly don't know — nor does it particularly matter.
Inevitably, this line of thinking eventually led me to questioning if Wordpress was the right choice for me. It was the tool I knew and was comfortable with. But was it congruent with the values I was developing? These doubts first surfaced on this blog when I published Craftsmanship and compulsion. Talking about the markup generated by Wordpress in serving this website, I wrote:
Then, the other day, I happened to peek under the hood of Jeremy Keith aka. Adactio’s website. I was looking to figure out how he had solved something related to IndieWeb features, to try to untangle how I could do the same with this site. What I felt while peeking into Jeremy’s source code (no innuendo!) must be similar to the experience of standing naked next to the human incarnation of a Greek god, representing the ideal of human appearance.
I felt shame for letting myself slide so far from this ideal.
Although I continued by downplaying a reshuffling of my tech stack as a consequence of this observation, I ended on a tread of ambiguity:
That’s to say, this website may look a little different tomorrow than it does today. When it does, feel free to sneak a peek below the hood.
Ten months later and, well, here we are. Feel free to sneak a peek below the hood. I'm quite proud of what you'll find there. But I'm getting ahead of myself. We've much to cover before getting to that.
The tiny nudges
I spent the months that followed exploring my options in a non-commital fashion. Hugo, Jekyll, Eleventy. I downloaded and explored cursorily all of the most popular options out there. Common for all of them, however, is that they featured a language almost entirely foreign to me.
Npm, git, frontmatter, jinjas and nunjucks and what not. Perhaps, like most things, simple and easy to grasp once you're familiar with it all. But to someone not well versed in this world it just made me feel stupid.
"Why does taking some content and wrapping it in some html and adding a bit of styling have to be so complicated?" I found myself asking. Before eventually dropping the matter entirely. Instead, I decided to double down on Wordpress. I knew my way around it well enough that I could customise it more or less entirely to my liking.
Through a combination of custom and public plugins, I managed to build a section on this website to replace Goodreads as my reading log. It wasn't perfect, but it worked.
Next up, I started thinking about how I could optimise the publishing workflow to my liking. I prefer to do my writing in plain text, sticking to plain Markdown for formatting. Maybe I could finagle a way to publish my text docs as posts automatically through the Wordpress Rest API? That would make it so much more convenient to publish notes and links from my phone, too.
But then little things started to annoy me. I spent a lot of time early this year customising the theme to my liking. And I took special care to stick to the visual editor to ensure that future updates wouldn’t break things. Despite all of my efforts, when an update to the theme rolled out, it completely messed up the look of the site.
Annoying. So I stopped updating. Instead, I created a plugin to remove update notices. Out of sight, out of mind. But then, out of nowhere, a core update suddenly left several parts of the site, most prominently the header, looking all wonky. Fixing it took me days.
Apprehension got to me.
Do I really want to spend time working on my site, tweaking the look and feel, adding functionality that can suddenly break with an update? My mind was all but made up. I essentially stopped working on the site, even if I continued to post links and notes. No use in putting in any more effort, I'm going to move away from this setup at some point in the not too distant future.
Then the Wordpress community blew up. I don't need to elaborate on that. If you're into Wordpress, you know, and if you don't, your life is all the better for it. For me, it was the push I needed to finally get my ass in gear and look for a new tech stack.
The goals
In parallel with this process my views on the web and technology have solidified. I've come to realise that I am not happy with the role tech occupies in my life, and I've begun taking steps to remedy the situation.
This journey of awakening has helped me formulate what's important and, conversely, what's not, as it relates to my personal website. These tenants have become the foundational principles for the stack of tools I want to use to create and maintain my website. They are, in no particular order, the following:
Uncomplicated
My tools should be so simple that even someone like myself — a regular lay person without any developer experience — can understand the gist of how they work.
Lasting
This website has been online for twenty years. I want it to last at least twenty more. And, what's more, I want to maximise my chances of conserving every single piece of content I have and will publish here.
Replaceable
In the case that something breaks, I want it to be easily replaceable. I don't want to wed myself to complicated processes that make it hard to move to an alternative solution. You never know what's going to happen. Even if it's open source, the software might turn out to be in the complete control of an absolute lunatic.
Compliant
Lastly, I want to do what little I can to make the web a better place. How can I do that? A small thing is to comply with the agreed upon standards of the web. That means using valid markup and styling.
The choice
These principles point me firmly in the direction of a simple, yet timeless approach: A static website. But, remember, I already looked at several options in that direction. They left me entirely mystified. So I found myself returning to that one question:
"Why does taking some content and wrapping it in some HTML and adding a bit of styling have to be so complicated?"
It can't be that complicated. Can it? Surely it can't...
My background
At this point, I should probably give you some background information on myself. I have exactly zero development experience. I flunked out of computer science in my early twenties because I couldn't wrap my head around the maths courses, and instead got a degree in finance and business admin.
(There's irony and social commentary to take away from that, I know.)
Until a couple of years ago, I had never written a line of code in my life. I once, long ago, made a concentrated effort to try and “get” PHP. It eluded me. Even with the help of Google, I always found it difficult to translate solutions to roughly similar challenges to something usable for me.
I had barely glanced at a command line since the nineties.
Then something happened: OpenAI made Large Language Models (LLMs) available to all with the release of ChatGPT.
Where I once found myself stuck trying to find solutions to a problem, I now had a personal tutor willing to explain and answer everything I couldn't quite understand. Where I previously simply lacked the language to express my logical flows in code, with the help of LLMs I could express myself in plain, written English, and the "machine" would translate it to code.
Sure, it's not "real" development. And real software engineers will scoff at the stuff "I" make. But it opened up a whole new world for me.
Where I previously found myself entirely depending on someone having already translated my needs to code and presented a graphical user interface for handling the code, I could now interface with computers through text and code. Since then I've increased my productivity significantly at work, taking advantage of LLMs to create scripts — mainly with Python — that automate tasks in ways I could only dream of a few years back.
When it comes to the making of websites, I have a little more experience. Well, that's to say, I have experience with using tools that create websites. It's probably been two decades since I last wrote HTML by hand — as opposed to relying on aWhat You See Is What You Get (WYSIWYG) tool of some kind.
But how hard can it be? I mean, really? And so it was decided.
I set out to recreate the look and feel of my website by handwriting the markup and styling. And then, armed with the help of an LLM, I would try to create a piece of software to automate the process of combining content, markup and styling to generate the HTML files that would make up the new version of my website.
The thinking
I went into this with a clear mental model of how I want a Static Site Generator (SSG) to work. (In fact, after some correspondence with my friend Fabian on the matter, I believe this is partly why I found it so difficult to wrap my head around any of the many great existing options out there already.)
Generating a page should involve four components:
- A content file: Everything I write is styled with basic Markdown. Ergo the content input should be in the form of plaintext files with the .md extension. I also need a way to specify some basic meta properties of the content in there.
- Top template: A file containing all the HTML that comes before the actual content.
- Bottom template: A file containing all the HTML that comes after the actual content.
- Style file: A file containing all the CSS that specifies what the site looks like.
I immediately ran into some shortcomings in my thinking. For one, I probably don't want every single piece of content to look exactly the same. My notes (shorter content) for instance, are visually distinct from regular posts. I wanted to stick with that convention. And for pages that sit outside the regular reverse chronological timeline, I don't want to display any meta data at all.
So I'm going to need a couple of content templates.
Then I started thinking about how I might want to use this setup to create and maintain other websites. In that case, it makes sense to move some stuff out of the script and templates. Like site name, home page and so forth. After some back and forth, I discovered that’s the purpose of this YAML thing all the various SSGs I've looked at had been talking about.
So now I have a settings.yaml file.
Building the site should be incremental
People often talk about build times when referencing SSGs. That always confused me, because how often do you need to rebuild everything?
I'm a simple guy, so I like to keep it very simple. To me, that means that when there's one piece of new content, we generate one new page and regenerate the relevant archive pages. And then you regenerate everything if you make template or styling changes.
(In hindsight I realise that this entire premise falls flat once you include more "dynamic" page components like related content, recent content and so forth. Luckily, that's not something I had intended to include in my setup.)
When in doubt, use a spreadsheet
When building archives, feeds and the like, you need data to decide what to include and information about the stuff you're including. I have absolutely no idea how regular SSGs handle this. I don't think any of them use a database. Maybe they compile a temporary index during the build?
That wasn't going to work with my incremental build approach. And I definitely didn't want to use a database. So I turned to what everyone who's ever worked in finance or accounting considers their second home: A spreadsheet.
I guess technically a Comma Separated Values (CSV) isn't truly a spreadsheet. But it's data presented in a tabular form, so close enough for me.
So for every type of content I want to represent in a list of some sort, like posts and notes, we should create a simple CSV index file that lists all content entities. When new content is added, we add it to the index, which in turn can be referenced to create updated archives and feeds.
Tying it all together
That's it, really. To summarise, the entire flow should look like this:
- A content file is added to a
content
directory. - Generate the HTML document using the top, bottom and content template files, a stylesheet and a settings file The content from the content.md file is injected into a designated spot in the content template.
- Add the piece of content to the relevant index file (if relevant for the content type).
- The content file is moved to a "processed" directory to indicate that it has now been processed.
- Repeat for every other file in the
content
directory. - When all content files are processed, regenerate archives, feeds and home page by referencing the index files.
The work
With the decision finally made, I eagerly opened up a new tab with Claude and got to work. From the get to, I set out to mindlessly reconstruct the architecture of my Wordpress site. That meant five post types (page, post, note, link and book) plus a double digit number of taxonomies. A whole lot of archives.
All was going quite well. Save a few details here and there, I was close to getting the script working as intended. (Remember how I said I would start with first recreating the markup and styling? That didn't happen.) But, as I was trying to iron out a few final things, and having trouble staying on top of what was going on where and how everything was put together, it dawned on me that I'm completely overthinking this.
I took a step back. How much of this did I use simply because Wordpress made it easily available, or perhaps even necessary?
Do I really need all these post types?
Are ten different types of archives with separate templates, pagination and what not really necessary for a personal blog?
And, if I'm being honest, do I really want to create a new "post" (type "book") and update it to track my book reading? (Spoiler: Heck no, I don't. But that's how I was able to do it with Wordpress.)
So I threw everything in the trash and took a few days to let the dust settle.
A blank sheet
The second time around I took the opposite approach. Start with the absolute basics and add only what's necessary. So I created two "modules":
- A main executable file to orchestrate the process.
- A module to create a new HTML page based on a content file, two templates (top, bottom) and a style file.
Getting this to fly was fairly quick work. I think I got it all done in an evening after putting the kids to bed. That feeling of finally having something in place was intoxicating. It spurred me on, and the coming weekend I spent far too much time in front of my computer.
Next on the agenda was creating the archive page and front page. My only objective at this point was to keep it as simple as possible. Case in point: The post archive page. Once done with that, the front page was a breeze, too.
Cookin' the look
With the main functionality in place, it was time to start working on the templates and styling. Doing this without having to consult an LLM felt vitally important. This is, after all, the stuff that actually goes "out there" for everyone to see. So I wanted to fully own every single line of markup and styling.
As mentioned, I spent a lot of time creating and tweaking the look and feel of this site through the Wordpress site editor less than a year back. The design, as it were, felt like something that was truly my own. I quite like it! My goal was to reproduce it to the best of my abilities through handwritten HTML and CSS.
The only problem was that I didn't really know anything beyond the absolute basics of HTML and CSS. Luckily, it turns out — contrary to the overwhelming hodgepodge of markup and styling generated by the Wordpress site editor — you can create the look and feel of this website without having to venture significantly beyond the absolute basics of HTML and CSS.
That's not to say I didn't spend a fair bit of time jumping between peeking into the source code of my favourite blogs and checking out W3 Schools' many excellent resources. Trust me, I did.
In the end, however, I managed to reproduce the design to my liking. Then, with full control of the source code, I even made some improvements. For one, I never liked that links weren't consistently styled. Now you won't find a link on this site that isn't underlined. Furthermore, the truncated header menu that wouldn't show all items on mobile was a result of my inability to get it to break properly with Wordpress. Fully in control of the markup and styling, I could modify the flexbox to behave entirely to my liking.
And, lastly, I did away with anything in the source code that didn't feel strictly necessary.
I don't care about social media link previews, so I don't waste precious bytes defining what those should look like for this website. Nor do I need to rely on your computer's processing power to create any fancy features to share my thoughts, so I threw away all javascript.
To finally have the control that allowed me to be this opinionated in how I created my website felt wholly liberating. As if I'd finally turned the table in a small, but significant way, and taken control of some technology that had held me firmly in its grip for years and years.
What's more, I can't even express how much joy and pride I took from seeing a website I've made — me! — validated.
Permalinks
At some point in this process, probably around this point, I had to make a decision on permalinks. What should the URL structure for the site look like?
For a brief moment I considered going retro. That is, just a bunch of files in the root public directory. The about page would be lars-christian.com/about.html
while the now page would be lars-christian.com/now.html
and so on. This comes with the added advantage of working anywhere you can host files.
But then I wanted an easy way to distinguish between posts and pages, so I considered prepending posts
to posts. And then I thought, well maybe I'll just keep them in a sub-directory, /posts
. And at this point I was like well what the heck, might as well just use clean URLs.
The way this works is to create a unique directory for each entry, and save the actual document to be served as a file called index.html
in that particular directory. When the web server gets a request to the directory, it serves up this document. Simple and elegant.
I did end up changing the permalink structure for the content, though. I wanted the URL to indicate when content was published. At some point I started avoiding that practice for "SEO reasons". With SEO no longer a concern of any note, there was no stopping me now! It did give me a bit of work in compiling a redirect list forwarding all the old content URLs to the new ones.
Images
It's not too often that I include images in my posts. But sometimes that's appropriate. Necessary, even. So I knew I needed to handle images somehow. It just had to be a really simple way of doing it. And by that metric, I think I nailed it.
My approach is this:
In my content
folder (where I store the files to be processed by the site generator) I have a subfolder called images
. This is my "media library". Any image I want to use in a post I store here. I then use standard markdown notation to reference the image — but only by file name. Here's a sample:
The image file name is justasampleimage.jpeg
. To insert it into a post I use the following in my document: ![This is the alt text, I guess](justasampleimage.jpeg)
(The only downside is that it is impossible to remember what goes where when using markdown to reference an image. I have to look it up every time!)
When the script generating the HTML file encounters an image reference in the content file, it simply copies that image file to the directory where the index.html is being saved. So the image shown in this post is stored at:
https://lars-christian.com/posts/2024-11-13-from-wordpress-to-windrunner-ssg-making-my-own-static-site-generator//justasampleimage.jpeg
I like this approach because I don't have to think about storing references to images somewhere and then pulling that reference from somewhere. All I need to remember is the file name. And I can easily reuse the images across various posts.
But what about responsive images? Well, I'm glad you asked. For my use case, that's not worth the hassle. I try to be mindful of keeping the (very few) images I use at a low enough resolution that they don't become problematic no matter your connection speed or bandwidth limitations. And I then use some simple CSS to ensure that the image is displayed at a size appropriate to your screen.
Alright but storing multiple copies of the same image is surely just wasting everything that's good about local caching? Yes, you're right. In a trade-off between reduced complexity and increased efficiency, I prioritised the former. To justify that decision, see my argument above about keeping image sizes low. It's also quite rare that I reuse an image. (But I like knowing that I can do it easily enough!)
One exception is images used in templates. Currently there are none, apart from the site icon. Nevertheless, I can't go around storing and referencing duplicates of files that are used on every page. So the site generator doesn't do anything about image references in templates.
Instead, I just prepend a /
when referencing the images in templates, and then process them in the exact same way as mentioned above — but only when generating the front page. That way the referenced image files are copied to the root directory, and thus correctly referenced from all other pages.
(Literally as I'm writing this, I realise that I could just use the exact same approach for all other images too. Referencing images would be just as easy, but I wouldn't have to duplicate any files. I don't know why I didn't think of that before!)
Updates
Yet another challenge is how to handle updates. Although it's good practice to proofread and edit before hitting publish — that's not something I'm particularly good at. I like to write, get it out there and then be done with it. That, of course, only leads me to frantically making dozens of edits across numerous republishes of the page as I scramble to make it look at least halfway coherent because now it's already out there, after all.
In other words, I need a quick and easy way to handle editing. Do I solve this by assigning each post a unique ID that I can reference somehow in the content document? That sounds like a bit of hassle.
I would like it better if I could just bring up the content document, make changes, and save it to have the changes published. Turns out, with how I'd structured the processes, that was already the outcome. The permalink/directory structure is created by combining the date and title of the post. That means that if I save a content document with the same title and publishing date to the content
directory, the newly generated HTML file will overwrite the old one.
Excellent! One more problem solved.
A potentially confusing outcome of this very simple approach is that there is no true link between the content file and the generated HTML file. If someone else were to use this rig, they might (reasonably) assume that the way to edit a post is by simply updating the corresponding content file.
Generally, that would work just fine. Until you try to change the publish date. In which case you would just create a new version of the post on the new date. Luckily, I know (although will no doubt forget it by the time that it becomes an issue) that the simplest way to handle this is by regenerating the full site. Or, alternatively, I can manually delete the originally generated HTML file and remove the entry from the index CSV file.
Bells and whistles
The basic functionality (create a post, update the archive and front page) and the design were now in place. Now it was time to decide how much complexity I really needed to add.
How many post types? What about tagging? And reading tracking?
I considered sticking to a single post type. "Do I do this for me, or for them?" I asked myself. Knowing that in this, there is no them. There's only me, so I can do whatever the heck I want. After much contemplation, I decided that I needed two post types. Separating short content that takes little effort (notes) from more traditional posts encourages me to publish more.
Realising that doing away with separate notes would inadvertently make me feel some sort of faux pressure to publish something more substantial at a higher frequency, I could see from a mile away that the end result would eventually be no activity here at all.
So I replicated the modules that process posts and generate the archives, and created a separate content template for notes.
Tags, on the other hand, I decided to leave out. At some point I got the idea that tags might be good for SEO, and I've stuck with them ever since. LOL! In truth, though, I still tag every piece of content for my own benefit. I just find it hard to maintain the sort of consistency in tagging that my obsessive-compulsive tendencies make me feel displaying them on the front end should warrant. Well that, plus I really didn't want to introduce tag archive pages. Those always felt like pure junk pages to me.
(I do like Rach Smith's single page approach, though. One day, maybe!)
Finally, I didn't need much time to decide that the way I'd set up my reading log was not something I wanted to reproduce. In case you hadn't caught on to the fact already, I'm a spreadsheets guy, and this is a prime example of spreadsheets were truly made for. So now I'm back to tracking my reading in a super simple spreadsheet.
But, I'm already thinking about how I can use that spreadsheet to automatically build a public reading log here on my website. So don't be surprised when that section makes a comeback.
The result
You're looking at it!
On 30 October 2024, I deleted everything Wordpress-related from my server's public directory. Immediately after, I uploaded the static version of my website that was generated by Windrunner SSG.
Yeah, that's what I named it (because, of course it needs a name):
Windrunner SSG
No big story to it. I just like Brandon Sanderson's The Stormlight Archive a lot. And thus, this piece of software (or whatever the correct term is for a couple of scripts orchestrated from a command line executable) became Windrunner Stormlight Spren Guardians, or Windrunner SSG for short ;)
Here's what my current flow for publishing new content to the site looks like:
Step 1: write
I do all of my writing in plain text, using Sublime Text — my favourite text editor! When I'm done writing and editing ;) I save the text file to a specific directory. Within a couple of seconds, the post or note is live, and the front page, archives and feeds are all updated.
Step 2: publish
I have a background script running that monitors my content
directory. When a new file is added, the script automatically triggers my new site generator. The content is processed according to what I've outlined above. In other words, a new page for the new content is created in the output folder, and the front page, archives and feeds are updated.
A second background script monitors the output folder. When a file is created or updated, it automatically connects to my sFTP server and uploads the new and modified files.
All the automation is taking place on an old Macbook I've set up as a "server" on my local network. That way I can publish from any of the devices I use to write, whether that's my regular laptop, my dedicated writing laptop or even my phone. I don't like writing on my phone, but in a pinch, it works well enough for a quick note.
That said, it's an overly complicated approach. Because why not? You could run everything from a single laptop. It would be much simpler and, honestly, work better.
The plans
With this move, I tossed out a lot of junk. Stuff that had no real value, but came bundled with Wordpress and thus was easy or even necessary to use. This current iteration of the site is absolutely barebones, and I already have some plans for functionality and content I want to incorporate into my setup in the future.
Some of it mimics or closely resembles what the Wordpress version of the site had, while other things are completely unrelated. Here's a non-exhaustive list, in no particular order, of things I plan to do with the site in the future:
Bring back old posts
While I was working on this new version of the site, the fantastic Internet Archive suffered a DDoS attack that left the archives out of function for days. It made me realise two things:
- I need to make another donation to the Internet Archive to help them weather the storm.
- I can't keep using the Internet Archive as my storage space for my old content.
So my first order of business is to bring back all the old content I can salvage through IA, and host it here as well. I need to get right on that.
Get the "Reading" section back online
My next priority is to get my book reading section back online. Like I mentioned previously, I hated logging my reading through the Wordpress admin interface. A spreadsheet is a much better experience.
That's why, as soon as I decided to move away from Wordpress, I set up a spreadsheet for the task. Much better! And, since it's stored on my home network, I can integrate it to my website build process easily enough.
I've already started charting out what the logic for that module will look like. What I can say is that it will be entirely driven by the spreadsheet. And I'm unsure whether I want to populate my notes feed with updates referencing my reading — when I start and finish a book, or mark one as "want to read".
It feels a little bit like junk content, to be honest. Right now, I'm thinking that it's better to just write a note whenever I have something I actually want to share with regards to a book I'm reading. But still contemplating that.
Organise archive pages
The current archive pages for posts and notes are not great.
I like having all entries on a single page. With how lightweight the pages are in this new setup (62 kB uncompressed for a year's worth of notes) I don't think the size is a problem as such. Plus, since I don't have a search function in place (and no immediate plans for implementing one) having the ability to just cmd/ctrl + f
and search among all titles is something.
What the archive pages need, however, are anchor links and proper tables of content. My plan is to generate these based on year and month. I think it will make the archive pages significantly more user friendly.
Indiewebify a bit, maybe?
Throughout this entire process, it feels like I've come full circle on the whole Indieweb thing. When I first encountered the movement I thought "wow, this is great!" and that I need to implement all the things.
And, make no mistake, the Indieweb scene is filled with many great people whose writing I cherish daily. But when it comes to all these things like adding markup to content to make it more... social, I think? I'm not sure if we need all of that.
What's more indie than a simple and accessible website compiled of semantic and valid markup and styling, with a feed on offer to those who want to subscribe? That's my current thinking, anyways.
One thing that will certainly not be making a comeback is the comments section. I've veered back and forth on this one. Over the past year I've had comments disabled, enabled only in the form of webmentions from other sites, open with an onsite comment form and through native ActivityPub integration and, most recently, open on "all fronts" including backfeeding all ActivityPub interactions into the comments section with Brid.gy.
All of this experimentation has taught me one thing: There's very little engagement through comments these days. Over the past year, I've had probably ten times as much meaningful interactions through emails spurred by this blog than through the comments. To continue encouraging that, I am keeping an email me link below all posts.
But that's it for interactivity. At least for now.
Pretty feeds
A small thing, but one I'd like to implement nevertheless. RSS.Style has a great guide for prettifying your feed files in the event that someone uses their browser to open the feed file.
I think standardised XML feeds are the most underrated part of the open web tech stack, and I want to do what little I can to encourage more widespread adoption. Making the feed readable to humans is one such small thing.
That reminds me, I should probably try to make my feeds more visible through the navigation. Right now, you have to navigate to the Subscribe page through the footer menu to discover it. I need to figure out a way to feature the feed(s) more prominently.
Blogroll page
One more small thing I want to do to promote the small/ open/ indie/ insertfavouriteadjectivehere -web is share a blogroll page. I've previously abstained from doing this, because I know that maintaining it would be a hassle.
With my new setup that's no longer the case. All I need to do is add a step to the build process that generates a blogroll page based on an OPML export from my feedreader. That way, I simply have to do an export from my feed reader every now and then to keep my blogroll up to date. And I can easily include the OPML file, too, for anyone who might want to dump my entire blogroll into their feedreader.
The end
If you've come this far, I must ask: What's your secret?!
It took me several sittings to merely proofread this post. Detail took precedence over brevity for the sake of posterity this time around.
Nevertheless, thank you for reading. If you have any questions, please do not hesitate to email me. No social media notification can ever match the excitement of receiving a personal email from a real person — so any and all comments are welcome.
Postcript: I'm sure some of you might wonder if I plan to publish the code for my little piece of software. My answer is a resolute “maybe”. At the moment, it is very haphazard and unstructured — not to mention very poorly documented.
That said, if you've read this far and would like the files to play with for your own amusement, email me. I'll be happy to share everything I've got.