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)