Reimplemented and It Feels So Good

It may not look different (yet -- more on this below!) but this blog is now powered by Python instead of Jekyll.
Jekyll, a popular static site generator built in Ruby, has worked for me for several years. I began this blog in 2020, so it's been a 5 year journey.
However, I always had trouble with it. One issue I faced is that as I changed computers, it seemed that the Ruby Gems I had were all wrong, and updating them didn't work so well. Another problem I faced was that it seemed hard to customize the template.
Now, it's entirely possible I don't really understand Jekyll well -- particularly, how Ruby Gems or the Liquid language works.
That said, I was able to write my own system to display my blog's archives in Liquid. I found it really hard, mostly because of the use of double curly brackets (e.g., "{{}}") -- I found myself constantly forgetting to add a second bracket. In addition, doing basic calculations in it seemed odd to me. Consider this construction:
{% assign intmonth = intmonth | minus:1 %}
I had trouble getting used to typing "minus:1" instead of, you know, "-1".
In contrast, I have been getting more and more familiar with Python, particularly for manipulating text. I found myself wishing I could simply use Python to solve the various little problems I was facing with my blog -- after all, I was increasingly able to use it to manipulate HTML and CSV files.
However, I stuck with Jekyll. Even with the occasional troubles with Gems and the oddities of Liquid, it was working well enough.
And hosting it was (and remains) free via Github pages, so I was learning a little bit of the Git workflow, to boot.
Microsoft Makes a Move, and I Make a Countermove
Then, the inevitable happened: Microsoft doubled down on Github feeding into Copilot.
Microsoft, as we all know, bought Github in 2018. Now, I knew that before I started this blog, but since Github was (and remains) the home of so many FOSS projects, I thought it would be wise to learn more about it. And Jekyll makes it easy to host a static site with Github pages.
But lately I've been more and more dismayed about generative AI -- particularly due to my role as a professor. I think it's going to do damage to the education of my students. And with Microsoft bringing Github closer and closer to the CoreAI team, I just didn't want to feed the Microsoft genAI beast any more.
So, I finally sat down and started plottin' and a-plannin.' I started writing in Python.
An Absolute Beginner Uses Python to Do a Thing
It seems a little wild to me that I even tried reimplementing this static blog site generate in Python.
Here's the thing: I was an English major, and now I write books and teach media studies. I've not done any formal training in coding.
But I have dabbled for years and years with HTML and CSS. I'm comfortable thinking about the constituent parts of a website. Things have only gotten easier with HTML5, which uses good, semantic markup (e.g., <header>, <nav>, and <footer> tags). Well-structured text like that makes it easier to imagine ways to automate its generation.
Python works really well with text, and since HTML5 presents texts in patterns, finding ways to search text and recreate it via scripts has become, well, kinda fun.
Next, although I am moving on from Jekyll, it really taught me the joy of using Markdown to compose posts. Again, the Jekyll approach to Markdown includes well-structured front matter -- another right target for Python-based manipulation.
Then there's syndication. Jekyll automatically produces an Atom feed. Because of that, I had another well-structured document to draw on.
A final ingredient is CSS. I also owe a debt to Jekyll for introducing me to Sass, which is a wonderful way to make stylesheets by using variables and some basic math. I don't use Python to handle Sass, but I can use it to trigger a quick Bash-based Sass process to convert .SCSS files to .CSS -- and from there, put them into the right folder location for the site.
All of that -- my history with HTML5, my newfound love of Sass and Markdown, and the example of Jekyll's Atom feed -- set me up to have a handle on the needed parts of static site generation. I just needed to sit down and plan it out.
I used my previous Jekyll-based blog as a guide to write a 300-odd line Python script that could take the structured Markdown posts, interpret their frontmatter, style them with Sass/CSS, and process them into the same file system that Jekyll produces. I also managed to use the data from this process to build an Atom feed. And glory of glories, I made the Atom feed with only two errors according to the W3C validator!
But How to Preview It? Oh, Yeah: http.server
What really brought it all together, however, was a thing I'd long heard about but never tried: Python's built in HTTP server. It's so simple to start:
python3 -m http.server
I could run that in a terminal in the rendered folder and easily preview the site locally, just as I could with
bundle exec jekyll serve
Both of those allow for local testing of the site before pushing it up to a server.
So now I can run the Python generator and preview it with the Python server -- in seconds flat. And I can just upload the whole thing to a web server. Just as I did with Jekyll.
It's amazing, to be honest.
Next Steps
All of this is not just to move away from Github pages, or just to learn Python. It's also setting me up to do something I've long wanted to do: redesign this site. The current design (as of mid-2025) is wearing on me. I want to make this fresh. Of course, I can do so with Jekyll (again, using Sass), but I wouldn't feel confident that it would work easily. In contrast, after writing a Python site generator, I simply feel far more confident that I can get into the guts of this site and redesign it.
So watch this space (or the feed!) for changes.
Also, one thing I've always wanted to implement is an automatic tagging system. With my Jekyll site, I had to do tags by hand. (Yes, I know there's a way to automate it in Liquid, but now I feel capable of doing it in Python.)
Finally, I probably will put my script up on Codeberg, since I now have an account there. If do, just do me a favor: don't laugh too much at my shoddy Python skills. I'm still learning!
Truly, I am living the FOSS Academic Lifestyle Dream.
Comments
For each of these posts, I will also post to Mastodon. If you have a fediverse account and reply to my Mastodon post, that shows up as a comment on this blog unless you change your privacy settings to followers-only or DM. Content warnings will work. You can delete your comment by deleting it through Mastodon.
Don't have a fediverse account and you want one? Ask me how! robertwgehl AT protonmail . com
Reply through Fediverse