After five years wanting to refactor my blog's internals, and a few rushes along the years to achieve this, I finally did it, and pimped the blog's design so you can feel the change (two times rather than once!), dear readers.
The story begins at the end of 2016. At the time, I had already made a few web projects in the last two to three years, mostly in PHP. These projects are partially archived by the Wayback Machine, going from the oldest version of touhey.fr, archived in Aug. 2014 to other websites with my Minecraft player name from back then. I had also made the switch to Linux on my main PC just the year before, right before being a student at 42, and I was discovering static websites, making me want to make mine.
So I did the most basic generator possible, as a bash script using pandoc, which listed all posts, made a page per post, and a simple index with a header where I presented myself, all of it in HTML4 without CSS, inspired as I was by motherfuckingwebsite.com. Thus, my blog was born, with already a first post, fopencookie - make your own file streams!.
This period was short-lived; so much so that no archive of the site was done by the Wayback Machine, on which my website goes from an assembly-like presentation from May 2016 to the next version, in 2017. That's explained by the fact I quickly felt limited by both bash which wasn't a good pick for the task, as well as having to implement every modification I wanted in that language.
After some research, I decided to switch to Jekyll, a website generator with all of the features one would expect, such as managing blog posts, theming, plugins, and so on. I used an existing theme, Researcher, then modified it to match my style better, wrote a few more posts, added a basic multi-language system since I wanted to write content in both French and English, and voilĂ , I found myself with a new website!
For 8 years, I've therefore used a static website generator written in Ruby with an extension system in that same language. During that time, I've made a few changes:
A theme I ended up rewriting from scratch to try to make something that looked good to me and was responsive, i.e. supporting alternative screen sizes such as mobile sizes for an optimal reading experience.
This theme was entirely written in Jekyll Liquid, Jekyll's templating system. In this theme, I also added in the following:
Correct metadata for various protocols, notably OpenGraph and Twitter Cards;
A multi-language presentation and navigation system cobbled together with file extensions (e.g. .fr.md for Markdown files for the French version of the blog).
A switch to jekyll-assets, a very good asset management system. If you use Jekyll for your projects, I highly recommend it;
A plugin to compute my age (see myage.rb), in order not to have to think about updating it by hand every year;
A few static files, some referencing a directory not managed by Jekyll but by nginx on the server itself, in /up.
Note that the multi-language system has evolved between 2017 / 2018 and 2024. Sometime during this period, I've acquired the second-level domain touhey.uk, and therefore decided to migrate my English blog on thomas.touhey.uk, leading to the separation of the project into two separate directories with elements such as the theme repeating between both, so modifications on it had to be done on both versions.
Also, even though I tried to build a navigation system suggesting versions of each page in other languages, the system was misbehaving when the translation did not exist (e.g. for untranslated blog posts).
In the end, I found myself with a big bag of hacks, which were a mess to maintain and evolve. Also, I made the choice not to learn Ruby, since I already knew Python on the side. Note however that my blog was the only static website project of mine that ended up with this complexity; my many other static websites using Jekyll were far simpler, e.g. touhey.pro.
At the same time, starting from 2020, I started learning and liking writing documentation on some projects with Sphinx and reStructuredText, such as thcolor, thox, or later on, Cahute. The syntax, even though it initially constituted a barrier to entry since I was used to Markdown, ended up appealing to me. A post I read at the time really resonated with me; it highlighted that most flavours of Markdown were incompatible between them, as opposed to reStructuredText which was clearly defined and designed to be extensible using custom directives and roles. This argument resonated even more since on my blog, to inject some basic elements, or even code, I had to add Liquid or HTML directly into my Markdown file, and even though it worked, it felt icky to me.
Around 2021, I ended up being fed up with my system, and started various experiments to get out of my bag of hacks and use reStructuredText on my blog. These experiments resulted in the tool I use today: thblog.
Starting from 2021, seeing what I had, I gradually defined a wishlist, which included the following elements:
An extendable tool written in Python 3, which would allow me to write extensions in a language that I know and love.
Correct support for reStructuredText, so that I could write all of my content in this format;
Support for multi-output / multi-site from a single source, with manual translations and correct support for "alternatives";
Correct support for assets, with transformations, dependency detection and automatic HTML tag generation without preliminary declarations, resembling what I could find with jekyll-assets;
Support for static files and avatars, so that I can deploy certain files at specific places to hotlink them on other sites (e.g. /avatars/sili.png or /resume.pdf).
At the time, I had started exploring tools similar to Jekyll in Python, such as Pelican and yozuch, but they didn't seem appealing to me. I also thought about using Sphinx directly, but it didn't seem very appropriate to use with my blog. So in the end, I've decided to make my own tool in Python, which I've named thblog.
Before writing the tool, I started writing my blog's content as if the tool existed, imagining how it would work. I translated all of the blog, even the drafts, in reStructuredText, and organized these elements in the way I wanted them to be organized in the final version; the result appealed to me, so I started taking concrete steps towards a blog in reStructuredText.
The specifications for the tool were the following:
It was to be a private tool, specific to my blog. I wanted to avoid generalizing too early in the tool's development, so that it would answer my needs first before anything else;
It had to be made in Python, and take posts and pages in reStructuredText;
It had to build a version of the site that could then be published using scp or rsync, and verify links to examine which resulted in an error (404, host not found, and so on, as linkcheck does), and support live preview like sphinx-autobuild allows;
URLs must change as least as possible compared to the Jekyll version of the blog, since Cool URIs don't change.
Note however that I didn't want to support theming at first: since I'm making a tool tailored to my needs, there's only one theme, the one I'm making for my blog.
Also note these specifications are only for the initial version. A lot of features can be added from there, including:
Comments!
This could work using a little external system, since the blog keeps being a static website; I could use something like Isso;
Announcements on new posts!
We could have announcements in a textual cache (e.g. in YAML or JSON format) sent to Mastodon, IRC, or others;
Caches!
In that cache, we could store other data, such as statuses on Mastodon or Bluesky, in order to include details regarding the status without the reader's browser having to go get the information from the source, while still keeping control over the style of the status.
Pingback and Webmention, at least for reception!
The tool could also send messages with these when publishing a new post, with a little dedicated cache, which would also be versioned in order to repeat those at every publication. That being said, Isso doesn't mention these in its documentation...
Metadata, and other semantic web shenanigans!
I would like adding more metadata on my website, such as Dublin Core tags;
Other outputs than HTTP/HTML, such as Gemini/GMI or WML to try and make my website as accessible as possible!
Geekcode blocs with a dedicated Python module, to decode descriptions, validate the format, and produce web annotations;
A search bar!
Sphinx includes one with a little JSON file generated on building the website, so that searching is done on the client side;
Hashtags!
Those could be placed under post titles, in order to find content about similar topics;
Theming!
If the system works correctly, we could try including more themes, and possibly have per-site themes, as well as exporting the project for usage by other blogs;
And many others!
The technological stack I chose for the tool is the following:
docutils, for handling files in reStructuredText (decoding, transforming, rendering);
jinja2 for HTML/RSS templating;
babel for internationalization (i18n) and localization (l10n);
pygments for coloring the code;
click for the command-line interface.
The first theme under thblog, which ended up being used all through 2024, is still available on the Wayback machine; the current one, made in March 2025, is inspired from Lagrange, a browser for Gemini, with the Atkinson Hyperlegible Next fonts by the Braille Institute.
As was already the case while the blog was running on Jekyll, neither the tool nor the source content are open source, even though the exports are mostly under CC BY-SA 4.0, and even though I version the code and content using git in a private repository on Gitlab.com. On this, I agree with Josh Comeau on most of the reasons he describes in Why My Blog Is Closed-Source (not on the security aspect, though):
I believe in the fact that blogs must be personal and represent, especially for web developers, their way to build a website, their tastes and colors. Without stretching it to say that everyone needs a website, if you're going to do it, you might as well build something unique and not copy someone else's website and just update a few things;
I wish to be able to innovate without having to provide support for other users of the tool, or be responsible for another user's bad experience on another website that mine (I already do that on other projects, I don't want to do it on this one);
I wish to keep my drafts private, even though they're in the same repository to simplify my organization and publishing process.
That being said, the tool's development is still an experience I'd like to share, possibly in other posts; even though I don't want to give the fish away, I find it useful and satisfying to share a bit of the fishing rod that helped me fish it.
This blog keeps on being something I work on on my free time, without any constraint and when I want to work on my writing skills. This technological transition, even if it does not directly change the result, allows me to achieve more satisfaction in writing for the blog; I don't rule out writing more posts than in the last seven years.
However, during the years, I've grown a significant amount of ideas for subjects I'd like to write on in posts for this blog. Among the 15-ish drafts I've got, one can find among the longest:
A post on file paths, their syntax, their exceptions and other fun facts (there are a lot I've found), standards, and so on;
A post on database design for modern applications;
Posts around developing thblog, especially its usage of docutils.
Overall, I read and investigate on a lot of subjects in the context of both my personal and professional projects, my courses, and my discussions away from keyboards and various social networks. I recommend subscribing to the blog's RSS feed; there is one by available language, and I try to translate posts after the original language I've written them in.
See you in my next posts!