Anthony Harper

Senior Full-Stack Software Engineer | Healthcare Technology Lead

(727) 537-9134 · anthony.harper@gmail.com · Pinellas Park, FL

Static Site Generator Deep Dive

Overview

In organizing my content for my personal website, I noticed a need for some simple HTML templating, but I didn't want to tie myself to a framework. So I created a static site generator in Java that would take my site content in Markdown format and convert it to HTML using predefined templates. The resulting content is packaged into dist and that is deployed by the CodeBuild stage.

Technology selection

I chose to use Java largely because I hadn't built anything new in Java recently and I knew from experience that it would be well suited to my use-case. I decided to keep my dependencies as minimal as possible, and I ended up with CommonMark for Markdown (and commonmark-ext-frontmatter-yaml for front matter) parsing as my only dependency. Everything else uses standard Java libraries. I settled on using Amazon Corretto 25 because I knew it would be readily available for my CodeBuild stage later on.

Rendering approach

All of the site's text content is stored in a /content directory that contains only .md files and subdirectories for content collections. HTML templates are stored in /templates, CSS, JS, images, and miscellaneous files are stored in their own individual directories. When the generator runs a build, it scans only top-level markdown files. If any of those files specify a "collection" (literally just a directory with markdown files in it) then it will scan the directory of the specified name and render all Markdown files found there. Each file contains YAML front matter to define its template, title, filename override if any, collections, custom CSS / JS / metadata. The generator renders collections recursively, so a collection can have its own collections and so on. Regardless of the organizational complexity of the components that make up the site, the resulting structure is flat.

Token-based HTML template engine

I built a custom template engine that exists within a content namespace (not formally defined, but that's the convention I used for the tags), so that an HTML template will contain tags like: <content:additional-scripts/>, <content:header/>, <content:body/>, etc. which specify where generated content gets inserted into the template. If a page has a collection, the content of that collection is rendered into HTML, concatenated, and returned back to the page renderer as content to be appended to content:body (after the main content:body of the page).

Runnable in CodeBuild

A key consideration was making sure that I could write markdown content, commit my changes, merge into envs/prod, and see my updated HTML deploy automatically. To this end, I designed the site generator to run as a command-line application and wrote a simple build.sh to automate clean builds of the application. I used Maven (provided by Corretto25) to handle dependencies, compilation, and the determination of classpath. Then I wrote a buildspec.yml which runs build.sh and executes the site generator's build step using the resulting binary.