Switching my blog to a homemade SSG
2022-04-07 00:00:00 +0000 UTCWeaver is my minimal, no-frills, understandable-in-15-minutes static site generator I wrote to generate my blog. I also wrote it so I could better understand how my site was going from markdown to HTML and better understand how to make changes to the way my site looks, the way my site is structured, and the workflow I use to create the site.
Also I wrote it because I wanted to, not because I needed something specific or didn’t like the solution I was using before (11ty) or any of the other myriad SSGs I’d tried or looked at (Hugo, Gatsby, etc).
Weaver works by looking at all of the markdown files in the directory posts/ in the root of the repository. It takes every markdown file and generates a post based on the content and the frontmatter. This HTML post is then saved to the output/ directory, also at the root of the repo. Along the way, it builds an index of metadata (path to the output file in output/, title of the post, tags for the post, and the publish date).
Finally it sorts the metadata by publish date descending, generates a map of all tags, and returns the metadata and tags.
func buildPosts(t *template.Template) ([]sortedPost, map[string][]int, error) {
theFs := os.DirFS("./posts/")
markdownFiles, err := fs.Glob(theFs, "*.md")
if err != nil {
return []sortedPost{}, map[string][]int{}, fmt.Errorf("fs.Glob: %v", err)
}
index := make([]sortedPost, len(markdownFiles))
...
sortIndexByDate(index)
tags := generateTagsMap(index)
return index, tags, nil
}
This is made easy by the great Go markdown, YAML, and standard library templating libraries.
Next Weaver generates an index page (the most recent five posts), an archive page (links to all posts on one page, for now), and individual tags pages (stored at output/tags/<tag text here>.html). Finally it links any custom CSS over from a static/ dir to the output directory.
And that’s it. If the environment variable WEAVER_DEV is set, it starts a static file server on port 3000 on the local host.
As the final step in this simple project going live, I learned how to set up a custom build process on Netlify. It’s easy – you just give Netlify access to the Github repo, choose the branch Netlify will pull, then enter a build command (in this case, go run.) and a directory where the site’s files will live (here, output/). And that’s it!
This is the first post I’ve made since finishing Weaver!
From here, I might add support for images, make some things in the main Weaver repo more generic, and incorporate my dependencies into the project as static files instead of getting them via a third-party CDN. Those dependencies are Pico.css and Prism.js for syntax highlighting.