Why I built another static site generator: A love story
Tags: django, python, staticsite, markdown
Published: 2022-03-20 03:51:16

Does the world _need_ another static site generator? Honestly... no. But, does it _deserve_ another one? YES!

It all started from this tweet:

![If I wanted to make a static website with just a few dynamic elements that didn't look half bad, what stack should I use?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/109qqvkhtejfad9uk3al.png)

I have used a few static site generators over the years including [Hugo](https://gohugo.io/), [Jekyll](https://jekyllrb.com/), and [Pelican](https://blog.getpelican.com/) to host my personal blog. And I have experimented with a few others including [Lektor](https://www.getlektor.com/) and [Gatsby](https://www.gatsbyjs.com/).

All static site generators do basically the same thing, but they each have their own idiosyncrasies. Since I have a lot of experience with Django (and a predilection to want to improve the Django ecosystem) when I saw the tweet above I thought, "why _wouldn't_ you use Django for this?"

The reasons _to_ use Django:

- it's already solved a lot of tablestake features:
  - creating RSS feeds
  - sitemap.xml generation
  - auto-reloading dev server
- a nice CLI management command system
- Django template language with lots of built-in template tags
- there is a huge ecosystem of other functionality

The reasons _not_ to use Django:

- it's "big" and "heavyweight"
- it's over-complicated

No programming language or framework is perfect, but the one I have the most experience with is Django. I love most of the Django, but I wanted to see if I could build an opinionated framework on top that hid all of the complexities of a normal Django site (e.g. serving static assets, complicated settings files, setting up URL routes, etc).

I wanted to make Django even more lovable by creating a simplified content framework that served markdown files in an intuitive way. So, [`coltrane`](https://coltrane.readthedocs.io/en/stable/) was born.

First, I used [django-microframework](https://github.com/wsvincent/django-microframework) as inspiration for a simple `app.py` that could be used instead of the potentially overwhelming files Django normally uses for a site. Then, I added in automatic reading of `.env` files to override Django settings that shouldn't be committed. I used [`markdown2`](https://github.com/trentm/python-markdown2) to automatically render markdown files into HTML. And built a way to load data from JSON into templates to be used as variables (since a database is not available when generating a static site).

Then finally, I built a management command that output the whole site as static HTML. The result is "yet another" static site generator, but a key differentiator is that it tries to be as simple as possible with sane defaults. There are only three commands:

- `poetry run coltrane create` to create a new static site
- `poetry run coltrane play` to start up a development server
- `poetry run coltrane record` to output a static site

After the site is created, just start adding markdown files into the `content` directory and they will be rendered as HTML using filename as the URL slug.

`coltrane` won't ever solve every use-case, but right now it solves two specifically for me:

1. It generates the static site of https://alldjango.com (building automatically on every `git push` by render.com).
2. It is used to serve https://devmarks.io/articles, as a Django app in an existing Django site

So, maybe the world doesn't _need_ another static site generator, but hopefully [`coltrane`](https://coltrane.readthedocs.io/en/stable/) is a fresh take on static site generators.

I would love for you to try it out for your next project and star the [coltrane repo](https://github.com/adamghill/coltrane) if it looks useful!