Blog

Writing a Static Site Generator in Nim (PART 1: How to Structure Content)

To start I looked at what options there were for templating in nim emerald is a DSL that seemed attractive because of the logic-related possibilities but I settled on moustachu an implementation of mustache in nim. Which has very little logic, as I realised I only wanted to iterate over some metadata.

The first issue is how metadata is represented in the blog content files. In pelican it's simply a block at the top of the file along the lines of:

Title: Writing a Static Site Generator in Nim (PART 1: How to Structure Content)
Date: 2020-07-13
Slug: ssg-1
Authors: Thomas Carroll
Summary: First part of a devlog looking at how to write a static site generator in nim

In my static site generator I chose to represent it as a json node with the format more like:

{
    "title":"Writing a Static Site Generator in nim",
    "date":"2020-07-13",
    "slug":"ssg-1",
    "authors":"Thomas Carroll",
    "summary":"First part of a devlog looking at how to write a static site generator in nim"
}

This more structured format allows me to pass it directly into nim's parseJson which can then be converted to a jsonNode object which can then be passed into moustachu's context constructor and referenced as {{metadata.title}} in the template. Specifically constructing a jsonNode for the whole article where metadata is a node itself. Then simply using nim-markdown I can add the article's content as a separate node for reference later:

article["content"] = %* markdown(articleFile[headerEnd+1 ..< len(articleFile)])

Nim has an interesting bit of syntax there ..< which is just the first index to one less than the last index.

Keeping the article as a jsonNode and not as the moutachu context will let me use the json to construct other feeds (such as json endpoints or rss/atom which is xml but still, a standardised structured data format is nicer for this)

Then writing the html files is simple, using the unescaped format in the templating ({{{this}}}) html can be directly embedded into a template.

Next to do is get the program to structure the output directory correctly, and to create meta-pages (such as an article index as in: this)

Back to Frontpage