Site Generation

History

I've maintained this site since 2014 and it was originally a WordPress site hosted on a HostGator VPS. With constant vulnerabilities being exposed via PHP made WordPress a platform I wanted to avoid and wanted the overhead of managing a site to be more-so about the content, not about patching plugins, etc.

Static site generation

In 2015, before renewing my yearly VPS contact, I noticed that running a small AWS instance would be around the same cost and the first year would be free due to a back-then promotional Free Tier; so if I didn't like it, I could shutdown the instance before my free period expired. There were some other benefits such as SSH access, iptables, and running my own code / webserver. For the same reason I stopped using WordPress, I did not want to run server side app code, which lead me to the use of a static site generator; this would allow me to serve static content and only client-side javascript code. And I would be able to serve it with a hardened Nginx configuration.

Jekyll

At the time, I was heavily invested in using Ruby for most things, where Jekyll was my choice of static site generator; it allowed me to write my content in Markdown via Ruby kramdown, plugins in Ruby, Ruby dialect for HTML templating, Ruby syntax highlighting with rouge. Ruby code was only used during generation, so what I was serving was static HTML / Javascript in the end, which satisfied my security concerns stated above. I introduced a webhook for automatically publishing new content when I pushed to my source repo via git; you can read more about this era of my site in an old blog post. I continued to run on Jekyll for years

Zola

I wasn't posting often and decided to move away from my AWS instance to a free-tier managed service, where I ended up choosing Netlify. It supported Jekyll and after playing around with it a bit, I fancied it's ease of use. I decided to re-design the site and ended up migrating to Zola, which had the same feature set and it was near a drop-in replacement for Jekyll. I was happy with one of the available themes and it provided some other features that I didn't need such as Sass/scss. The main benefit was Zola being a pre-built binary, where I didn't need any requirements to use it locally, where I could follow the same process as before on Jekyll; build / serve locally and then git push once I was satisifed, minus the Ruby dependencies.

Present

I stopped writing to the blog but would make small edits to living pages over time and found that Emacs rendered Orgmode very well compared to Markdown. Things like code blocks would be rendered in Orgmode as Emacs rendered them in their own specific language modes, instead of rudimentary code highlighting in Emacs Markdown mode. Also, formatting (bold, emphasis, inline code, ..), links, headers, which hides the formatting characters until you are editing that specific word; links only show their alias (if you set one), so long links are hidden, similar to how you would see them rendered, unless you start editing it or toggle the hidden aspect i.e. M-x org-toggle-link-display. In Markdown, they can be inline or indexed, the former is cleaner but both expose the whole link in the document, which can make it more cumbersome to read. I also use ~org-modern~ which makes the editing experience even better.

However, Zola did not support native Orgmode; yeah, you could convert with pandoc or have tooling to handle some of this but this didn't seem worth it. Also, Orgmode does have a native HTML exporter but this would leave much to be desired. And ox-hugo exists but after years of using pre-built SSGs and making my content fit the shape expected by the engine, each with their own caveats, I decided to roll-my-own and be done with it. Netlify supports go, so my intent was to use it.

Writing the generator was fairly simple, walking my .org files and line parsing, generating .html: First the org header lines, which start with #+, secondly, the Orgmode content formatting, which was possible with just a few rules i.e. converting links to anchor elements, src blocks to pre-code blocks, bullets to headers, lists to ol or ul elements and so on. The previous and current line types would be stored, so I could make a decision based on what the previous line was i.e. if I'm in a code block, don't process the line with usual paragraph rules, until we hit the #+end_src line, then we can close it off. At first, I had highlightjs loaded for syntax highlighting but after finding a bug that I could not fix easily with an upstream PR, I decided to create a very minimal highlighter in Go; I would only create rules for code I wanted to highlight and better yet, I would pre-render all of it instead of doing it during page loads like would have been done with Javascript based approaches. The only Javascript I use is for loading my ANSI banner using escapes.js. Content for each page, would be a single HTML formatted string, which generated the page with Go stdlib template/html, where I used templated .html for my single layout used for all pages. Page titles, tags, and dates were all stored in the org header of each .org file, which also fed the layout template, aside from the content string (which fed {{.Content}} in the layout). I include the domain in the template, so when I am hosting locally to validate changes, the links work (localhost by default if WEB_DOMAIN env var is not present during generation run)


data := TmplData{
    Domain: domain,
    Title: title,
    Page: page,
    Heading: heading,
    Content: template.HTML(
            fmt.Sprintf(`%v`, content)),
    BuildTime: time.Now().UTC().Format(time.RFC1123),
}
      

Once I clean up the code, I will host it in git and share here



Re-generated September 2026