Burger.

A brief look at my site generator, nng

Written October 17, 2024

I switched my website from my old website generator, needleful's personal site generator, to a full rewrite in Prolog, needleful net generator.

It was a fun little project, so I wanted to talk about it.

Why do I have my own site generator?

npsg and nng are both static site generators. Static site generators are kind of a solved problem, with dozens of them already available.

I made my own because I wanted to make a lightweight site without writing a bunch of duplicate HTML, but I didn't want to learn a bunch of stuff about an existing system. You look at Hugo or something, and there's a whole world of things I'd have to learn:

I already know a decent amount of HTML, CSS, and JavaScript, so it wouldn't make much sense to learn a whole new layer of stuff on top of that for a simple personal site.

Plus, I just like making tools.

How the generator works

My site is split into templates and pages.

For each folder, I first gather up all the templates. For a simple example, let's just look at a test templates.

<template name='with-params'>
	<param name='hello'/>
	<content>
		<p>Hello, <i>[[hello]]!</i></p>
	</content>
</template>

It has one parameter, hello, and it generates some content, swapping [[hello]] with whatever we put in the page.

Using the template would look like this:

<with-params>
	<hello>Gamer</hello>
</with-params>

And that generates the resulting HTML, unsurprisingly:

<p>Hello, <i>Gamer!</i></p>

There's also conditional statements, lists, expressions, and all the other things you would probably want:

<!-- a random example -->
<when val='n mod 2 == 0'>EVEN NUMBER DETECTED</when>

<!-- some snippets from my comics template -->
<foreach list='sources' it='i'>
	<img class='comic' src='/[[source]]' alt='Comic: [[title]] page [[i+1]]'/>
	<br />
</foreach>

<match val='src_file_exists(page + 1|".page.xml")'>
	<true>
		<li><a href='/comic/needleful/[[page + 1]].html' class='align-right'>Next</a></li>
	</true>
	<false>
		<li>Come back later!</li>
	</false>
</match>

It lets me focus on making content when I need to, but creating new templates is basically the same as making a regular HTML page.

My original solution was written in C# and .NET, but it was pretty limited.

The killer feature was finding a Markdown parser for Prolog, which I now use for the blogs.

My entire site generates in about 0.6 seconds. It's not smart enough to detect if a file needs to be regenerated, so that's the time to compile all 56 pages.

I think it's pretty cool.