Introduction

I've tried to make websites before, quite a few times, but I got to the stage where I would try to customise one thing or another and things would quickly fall apart. I probably started with self-hosted WordPress, I think I've lost that battle more than once and now I vow never to try again, I found it to be a mess of plugins, some chargeable, some free, some that worked, some that didn't, just a not very pleasant experience all round.

Among these attempts, I tried to use Jekyll, Hugo and Eleventy and there may have been others. I probably went furthest with Hugo and Eleventy but I never got to the stage where I was happy with the site I was building. I think the main reason for this is that I'm not a CSS wizard and when it came to tweaking things, I really didn't have the time to find out what element was affecting which part of a page in a certain format. It also felt like your choice of template would change a lot about the way files were structured and I didn't like the pattern of learning one, finding that I couldn't get something just right, learning another, getting ticked off with it all, etc.

So I knew how Static Site Generators (SSGs) were generally made up, I knew what a slug was, I've long been a member of some blogging related subreddits so there was some latent knowledge hanging around. I had half an idea of what I wanted my site to look like, but my lack of CSS knowledge was still a problem, but I dove in nonetheless.

Let me say before we get into it; I've probably made a lot of mistakes, I went into it fairly under-prepared and I'm sure there are better ways to do things, but I absolutely loved the process, the forced learning and the satisfaction of finally hitting the button to deploy my site made it all worth it.

Available Static Site Generators

I can find my way around Python, I've used it a lot when pulling data from various API endpoints and working with the data I get back, so I figured I could use that but at the time I wasn't aware that some other SSGs were built with Python. Hugo uses Go, Jekyll uses Ruby and Eleventy uses Node.js. There was a small voice in my head that said I should probably use one of these methods, there was probably a reason they used them, but it just didn't occur to me at the time to see if any others were built with Python and I just wanted to stick with what I knew.

I now know that you can go look on Jamstack.org to see a list of SSGs and what they are built with. I may well have been better off using one of these, but would I have followed through with it when I went around the same loop of getting frustrated with templates and CSS? I'm not sure.

Here are a few of the most popular Python-based SSGs that have an active GitHub repo:

  • MkDocs, aimed towards project documentation.
  • Pelican, a static site generator that requires no database or server-side logic.
  • Sphinx, geared towards documentation.
  • Lektor is a static content management system that runs offline.
  • Nikola is a static site and blog generator.

Here's a nice example of the pelican-bootstrap3 using the Pelican SSG, which you can find at https://www.daan.fyi/:

Pelican Bootstrap 3 example

My SSG

I struggle to recall exactly how I started but I think it was probably on the layout of my home page, because that seems important when you're starting out. However, I quickly realised that I needed to put some ideas down, I'd been jumping from one task to another without any thought about which depends on which and what should be focussed on. I needed a way of prioritising tasks and marking them as done, so I turned to Trello, nice and simple, free for a solo project and I've used it before so I knew what features I could use. Here is my initial list of requirements:

  • Articles should be written in Markdown.
  • A concept of featured articles.
  • A way to toggle between dark and light themes.
  • Navigation that loads on every page.
  • No server-side stuff going on (so it would be easier to find hosting).

The list grew quite quickly, but my naive self thought that was a good list to start with. I think I was wrong, still-now there are some things I wish I'd added in the early stages, but I'll get to that later.

Navigation

I'd done the colour scheme and the font and I'd built my list of requirements, but it was all such a huge learning curve, learning to handle Jinja templating, learning about CSS flex, looking back, the first couple of weeks are such a blur, I've no idea how I put so much time into it. I knew I needed to work on navigation. Hello ChatGPT.

I've stated in my Revealing the power of Custom GPTs article that I've built many custom GPTs and this is when I made another one. In my new GPT, I pre-loaded it with more a detailed explanation around my list of requirements, colour scheme details, file structure (as it was back then), and anything else I could think of that might be useful to know. I asked it what to do with my header and it came back with some sample JavaScript and CSS. It was a bit of a mess and the theme toggle was an ugly thing, but it was a good start and it wasn't long before I'd got it folding away into a burger thing below a certain screen width. It's still not perfect but it's good enough to go live with. I'd never really used JavaScript and it immediately struck me how much it looked like Python, I guess there are many similarities between different languages but I just hadn't really looked at it before.

Articles

I've no idea what my first attempt at converting Markdown articles looked like, but I can be sure that it looks nothing like it does now. I'm comfortable with Python but I lean on Google and ChatGPT to find modules I can import and use. The process now involves a few files:

  • Markdown Articles with Front Matter: The articles script actually ignores the front matter in the file itself, this is because the the last updated time is pulled from the metadata of the markdown file itself and the front matter is all pulled together in a different part of the process into a JSON file.
  • A collections_metadata.json file that I update manually with the Slug and Index of any articles that are part of a collection.
  • A template file that's used to generate the HTML for each article.

Minification and Purging

I had never heard of Minification or Purging (at least not in this sense) until a few weeks ago, but once you start getting robots crawling around your site, and looking at the feedback they provide, it's suddenly a topic you have to learn about, another topic!

Minifying something is just the process of removing all the unnecessary characters from a file, in my case, CSS and JavaScript files, so that it's smaller and quicker to load. Purging is the process of removing all the CSS and JavaScript that isn't used on a page or throughout your site, depending on how you map your files.

As it turned out, because I'd built the whole thing from scratch, there was almost no purging to be done, so I didn't bother, but it was a good learning experience and I'm sure I'll need to do it on future projects.

With minification though, that changed the way I would store my source CSS and JavaScript files, I now keep the original, readable copies in my src folder and it minifies them every time I run a full build.

Other Challenges

I didn't know I needed to create a robots.txt or that I needed sitemaps, but actually, when everything else is already in place, the sitemaps were very easy to generate. My biggest challenge outside of these things was customising the newsletter sign-up form, I didn't find much useful documentation on using my provider, so in the end I relied on ChatGPT to help me out from a standard form that was provided.

The full build flow

Now that the site is live and some of the early problems have been sorted out, the full flow of build items looks like this:

  1. I add articles I plan to write to an articles.txt file, no curly braces or anything fancy here. The first part of the build comes along and converts that into a Slug. It removes any small words, punctuation and spaces, makes it all lowercase, hyphenated and builds a file with a templated Front Matter, marking the article as hidden.
  2. The Front Matter and the time stamp are pulled from the Markdown files and this is all put into a JSON file.
  3. The About, Privacy and Contact pages are built from Markdown files and their respective templates.
  4. The articles are built as described above.
  5. The Blog Post and Home pages are built, these take into account the order in which the articles were created, or I can modify this manually in another JSON file.
  6. The sitemaps are created with timestamps reflecting when any page was last updated.
  7. Finally, the CSS and JavaScript files are minified and images are resized.

Lessons Learned

I feel like this is a good place to include a snapshot of what the site looks like right now (April 2024):

arrywalker.com

If there's a next time, and eventually I will circle back around and fix these problems with this site, I'll do a few things differently.

  • I want a sidebar, when I have enough articles, I want to be able to filter by tag or maybe even search by keyword.
  • As above, there is no search or filter function yet, I wish I thought about that early on.
  • I'd like the layout of the home page to be a bit tighter, I think I've got a bit too much padding in places.
  • I wouldn't call the site beautiful, it's functional, to a point, but I can see plenty that could be improved.

Conclusion

No regrets, I've absolutely loved this as a project, I've probably half-heartedly attempting this on and off for about 25 years, I got into Dreamweaver when that was a thing. But there is plenty of room for improvement. My experiences with other methods of building a site certainly gave me some latent knowledge that I used to build the structure of my own SSG, so it was all just a very long preparation for this moment. But this clearly isn't my day job. I'm at home with Cloud Automation, large-scale Terraform deployments and Python, and now, if only to a small degree, I can call myself a (lightweight, and fairly slow-moving) web developer.