The Simplest Static Site Generator
Tags: html, webdev, tutorial
Published: 2024-01-07 17:42:16

Sometimes, you want to build a simple HTML page and populate it with some data. You may have some JSON lying around and want to make a simple website to visualize its contents. Or perhaps you want to show off [how many books you read](https://www.hansschnedlitz.com/bookshelf/) in the last few years.

In any case, we’re talking about a small set of data and a _single_ HTML page here. Would you use a static site generator for that? Which one? Jekyll? Hugo, Gatsby? Isn’t that overkill for what we’re trying to do?

I was pondering questions like this when I came across [Pandoc Templates](https://pandoc.org/MANUAL.html#templates). Turns out there is a way to generate static sites that is much simpler than most other options out there.

Alright, this might not be the absolutely simplest way to generate a static site. You got me. I bet someone, somewhere builds their static sites using a one-line Perl script. Jokes aside, let me know if you find an even simpler approach to building static sites.

## Enter The Template

A Pandoc template is not much to look at. It’s just an HTML file filled with some special syntax sprinkled in. Syntax that allows you to write [conditionals](https://pandoc.org/MANUAL.html#conditionals) or [loops](https://pandoc.org/MANUAL.html#for-loops) as well as do some other stuff. Let’s say we want to list authors and their respective books to simplify things. To do so, let’s create `template.html`:

```html
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="date" content="$date-meta$" />
    <title>$title$</title>
  </head>
  <body>
    <section>
      $for(authors)$
      <h2 class="author">$authors.name$</h2>
      <ul>
        $for(authors.books)$
        <li class="book">
          <a href="$authors.books.link$">$authors.books.name$</a>
        </li>
        $endfor$
      </ul>
      $endfor$
    </section>
  </body>
</html>

```

Now that we have a template, we must populate it with some data. I’ve found the most uncomplicated way to do so is to create a markdown file that contains the data as [metadata](https://pandoc.org/chunkedhtml-demo/8.10-metadata-blocks.html#extension-yaml_metadata_block). We keep our data in `authors.md`.

```yaml
---
title: Authors and their Books
authors:
  - name: James S.A. Corey
    books:
      - name: Leviathan Wakes
        link: https://www.goodreads.com/book/show/8855321-leviathan-wakes
      - name: Leviathan Falls
        link: https://www.goodreads.com/book/show/28335699-leviathan-falls
  - name: Margaret Atwood
    books:
      - name: The Handmaid's Tale
        link: https://www.goodreads.com/book/show/38447.The_Handmaid_s_Tale
        
---

```

I found Markdown documents with embedded metadata easy enough to work with. If you prefer specific JSON or YML files, you can use the `--metadata-file` flag to pass them to your template. See also the other [reader options](https://pandoc.org/MANUAL.html#reader-options).

Then, run [Pandoc](https://pandoc.org/) to generate your static site. And that’s it.

```bash
pandoc --standalone --template template.html authors.md -o index.html

```

I’ll take Pandoc over other options every day of the week for this particular use case. What about you?

## I Don’t Want to Install Pandoc!

I know, right? I don’t want to either. Let’s use Docker instead. Put this into your `.aliases` and use `pandock` rather than `pandoc`.

```bash
alias pandock='docker run --rm -v "$(pwd):/data" -u $(id -u):$(id -g) pandoc/latex'

```