<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <title>The Blog of Harry White</title>
  <link>https://harryw.au/</link>
  <description>A blog about programming and other such things</description>
  <language>en-au</language>
  <managingEditor>harry.white424@gmail.com (Harry White)</managingEditor>
  <webMaster>harry.white424@gmail.com (Harry White)</webMaster>
  <generator>My python script :)</generator>
  <lastBuildDate>Thu, 23 Apr 2026 18:56:36 +1000</lastBuildDate>
  <item>
    <title>What I wish I knew before writing my own static site generator</title>
    <link>https://harryw.au/posts/static.html</link>
    <pubDate>Sat, 18 Apr 2026 18:41:00 +1000</pubDate>
    <description>&lt;p&gt;In creating the website you are hopefully reading this on now I decided to write my own static site
generator rather than using something like &lt;a href=&#34;https://jekyllrb.com/&#34;&gt;Jekyll&lt;/a&gt; or &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. My main reasoning for
this was I wanted to end up with something that felt uniquely mine and figured it would be easier to
do it myself rather than understanding something like hugo&#39;s configuration at a deep enough level to
make that happen.&lt;/p&gt;
&lt;p&gt;Initially I figured I would do it with a Makefile and a couple of small python scripts for some
templating and markdown compilation. In the end I still did use make and python, but like many
software projects I may have underestimated things a tad.&lt;/p&gt;
&lt;h2&gt;Commonmark is good actually&lt;/h2&gt;
&lt;p&gt;One of the goals for my static site generator was to have as few dependencies as possible, as I want
this site to be as easy for me to maintain going forward. If I come back to it after many months I
absolutely don&#39;t want to be messing about with dependency upgrade hell.&lt;/p&gt;
&lt;p&gt;One of the first decisions I had to make what which library to use for compiling markdown to html.
After a very quick search I chose the most popular package just titled &lt;a href=&#34;https://pypi.org/project/Markdown/&#34;&gt;Markdown&lt;/a&gt;.
While it did work fine I was not massively impressed with it&#39;s documentation and plugin system.&lt;/p&gt;
&lt;p&gt;I was also aware that the &lt;a href=&#34;https://commonmark.org/&#34;&gt;commonmark spec&lt;/a&gt; existed and standardised the
main syntax of markdown, meaning you could write something that was compatible with many different
libraries. Markdown (the library) did not support commonmark and I thought it would be a good idea
for the blog to use something that did so I could more easily swap out the library if needed. From
a quick search it seems other people have had compatibility issues with my original choice as well.&lt;/p&gt;
&lt;p&gt;Anyway in the end I chose &lt;a href=&#34;https://pypi.org/project/markdown-it-py/&#34;&gt;markdown-it-py&lt;/a&gt; and this has served me well. Definitely
a lesson that going with the biggest most popular library is not better for ease of maintenance than
something that is standards compliant.&lt;/p&gt;
&lt;h2&gt;Frontmatter, we kind of need that&lt;/h2&gt;
&lt;p&gt;In my markdown files I use some frontmatter which looks something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;My very cool post&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;author&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Jane Lane&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;published&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2025-11-06T17:10:00+11:00&lt;/span&gt;
&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This practice is basically stolen from other site generators as far as I can tell, but it isn&#39;t
really standardised. Which means that your average markdown library doesn&#39;t actually know how to
deal with it out of the box, but most seem to have plugins to handle it.&lt;/p&gt;
&lt;p&gt;Initially I did use the plugin for &lt;a href=&#34;https://pypi.org/project/Markdown/&#34;&gt;Markdown&lt;/a&gt;, but it&#39;s API was a little weird and it
didn&#39;t actually support proper yaml, having it&#39;s own simpler syntax instead.&lt;/p&gt;
&lt;p&gt;So in the end I thought if I was going to use a basic syntax anyway I might as well write my
own. I ended up with a simple system that reads key value pairs separated with a &lt;code&gt;:&lt;/code&gt; and optional
whitespace, then I just manually convert from string to other types when constructing my &lt;code&gt;Meta&lt;/code&gt; type
which holds this metadata.&lt;/p&gt;
&lt;p&gt;But the real advantage of all this was that I could have it completely separated from my choice of
markdown library, I just pass the file object to my frontmatter code which reads everything between
lines containing &lt;code&gt;---&lt;/code&gt;. Then pass the same file object to the markdown library to read the rest of
the file as markdown. This worked well when I later replaced the markdown library and didn&#39;t have to
touch the frontmatter code or mess about with plugins.&lt;/p&gt;
&lt;h2&gt;Custom fonts and subsetting&lt;/h2&gt;
&lt;p&gt;As part of the whole &amp;quot;making it feel like my own&amp;quot; thing. I knew I wanted at least one custom
font and &lt;a href=&#34;https://fonts.google.com/specimen/Jacquard+12&#34;&gt;Jacquard 12&lt;/a&gt; took my fancy while browsing Google Fonts one day.&lt;/p&gt;
&lt;p&gt;I also got into the idea of font subsetting after reading the excellent blog &lt;a href=&#34;https://www.jonoalderson.com/performance/youre-loading-fonts-wrong/&#34;&gt;You&#39;re loading fonts
wrong&lt;/a&gt;. The idea being that if you are only using a small subset of characters in
a font you are actually wasting bandwidth and making your site slower by loading the entire font
instead of a subset with the characters you actually use.&lt;/p&gt;
&lt;p&gt;In my case I was able to add an extra step into my Makefile that converted the full font into a web
font with just ascii characters and the bar character (&lt;code&gt;|&lt;/code&gt;) that I am using as a separator.&lt;/p&gt;
&lt;p&gt;With all of this I was able to move away from using Google Fonts to serve the webfont file (which I
already wanted to do as I find it uncomfortable from a tracking point of view) and end up with a
more performant site in the process.&lt;/p&gt;
&lt;h2&gt;Getting the damn thing to not look terrible on a phone&lt;/h2&gt;
&lt;p&gt;After setting up most of the site I was having this problem where everything looked great on my
laptop but viewing it on a phone (which I where I read most blogs at this point) the text looked
super small, almost unreadable. And I knew that with the CSS setup I had, it should be scaling up.&lt;/p&gt;
&lt;p&gt;It took me way too long to realise that I needed to define a device width viewport which can be
done by just adding &lt;code&gt;&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1&amp;quot;&amp;gt;&lt;/code&gt; to the
&lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of the page. Without that a mobile device will actually render at a larger size and then
&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/CSSOM_view/Viewport_concepts#mobile_viewports&#34;&gt;shrink it down to fit the device&lt;/a&gt;. This works ok on websites that aren&#39;t designed
for mobile, but is terrible otherwise and seems to mostly be a hangover for when the web was almost
entirely built for larger screens.&lt;/p&gt;
&lt;p&gt;All this made me realise that something like a basic HTML document with all the sane defaults would
be useful. But I didn&#39;t find anything like that in my brief search.&lt;/p&gt;
&lt;h2&gt;Accessible contrast is good and easy&lt;/h2&gt;
&lt;p&gt;Like most people probably do I spent a bunch of time messing with colour schemes and deciding on
how I wanted everything to look. Which is fun and all, but it is surprisingly easy to end up with
something that doesn&#39;t pass the accessibility standards for contrast (WCAG).&lt;/p&gt;
&lt;p&gt;But this is actually a very easy thing to fix these days, it turns out pretty much all browsers
now have a WCAG checker built in to the colour picker in dev tools. The one in Firefox gives you a
little tick for AA or AAA when messing about with colours and makes it super easy to keep it green.&lt;/p&gt;
&lt;p&gt;After a bit of fiddling with colours the result was easier on my eyes too.&lt;/p&gt;
&lt;h2&gt;RSS is a mess of a specification actually&lt;/h2&gt;
&lt;p&gt;One thing I knew I wanted on the site was an RSS feed. Seemed simple enough until I actually started
having a look at the &lt;a href=&#34;https://www.rssboard.org/rss-specification&#34;&gt;RSS specification&lt;/a&gt; over at the rssboard website.&lt;/p&gt;
&lt;p&gt;If you are used to reading thorough specs from RFC&#39;s this is a bit of a step back. For a start the
site has ads all over the place, then there is the very confusing versioning with the sidebar saying
2.0 is current, but there are also mentions of 2.0.11 and 2.0.1 in various places.&lt;/p&gt;
&lt;p&gt;At least they do have an RSS validator on the site which would be great as something like a command
line tool I could lint my output with instead of having to paste in a link once it&#39;s already public.&lt;/p&gt;
&lt;p&gt;All this did make me appreciate &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc5023&#34;&gt;the atom protocol&lt;/a&gt; a lot more, but I ended up sticking
with RSS as I assume it has better compatibility and I had already dealt with the issues. May
revisit that in future though.&lt;/p&gt;
&lt;h2&gt;Incremental compilation is hard&lt;/h2&gt;
&lt;p&gt;Using &lt;code&gt;make&lt;/code&gt; has in general been positive, I can just write my python commands to process individual
files and have make deal with passing in dependant files and calling everything in the right order.&lt;/p&gt;
&lt;p&gt;At the start this was very simple, but it did get a bit complex as things grew and I did run into
some peculiarities, like that folders don&#39;t actually update their timestamps when files in them
change! Which is just a standard unix behavior I had apparently not put much thought into before.&lt;/p&gt;
&lt;p&gt;It also did get a bit tedious specifying all the dependencies at some point, because of course you
have to deal with things like what should rebuild if the code of the static site generator changes.
Then once I started using templates a bit more you need to make sure &amp;quot;base&amp;quot; templates used across
the site also re-build all the posts.&lt;/p&gt;
&lt;p&gt;Now that it&#39;s up and working though I feel like the maintenance will be small, but we will see.&lt;/p&gt;
&lt;p&gt;The performance of all this is not &lt;em&gt;amazing&lt;/em&gt; with a full re-build taking close to 3 seconds, maybe
if I really get into &lt;a href=&#34;https://wolfgirl.dev/blog/2026-02-23-so-ive-been-thinking-about-static-site-generators/&#34;&gt;SSG speed&lt;/a&gt; or my site grows a bunch I would re-think it.&lt;/p&gt;
&lt;h2&gt;Stopping the tinkering to actually write something!&lt;/h2&gt;
&lt;p&gt;As fun as tinkering with all this is I did end up doing that a bit too much instead of sitting
down and actually writing a post. After all what use is a site with nothing of substance on it.&lt;/p&gt;
&lt;p&gt;I did come across &lt;a href=&#34;https://lmnt.me/blog/how-to-make-a-damn-website.html&#34;&gt;How to make a damn website&lt;/a&gt; while working on this, which makes that
point really well and has great general advice too.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Anyway it has been a fun time, guess I should go back to writing the blog post I actually created
this site to write, rather than getting distracted for several months and writing about the site
itself. Oops&lt;/p&gt;
</description>
  </item>
</rss>