Adding templates to your static website with mynt and jinja2

» Python, Tech

…is what this page is a result of and this post documents my progress!

Introduction

I’m working with Django all day so naturally I often use it for side-projects. Have you ever had a situation like this, though:

This teeny-weeny website I want to make does not warrant a full-blown framework, let’s just write some HTML!

Having taken this perfectly reasonable decision, you make the website and everything is fine. That’s how it was with this very website.

For some time, that is. Then you add pages, make changes in the menu, change the footer, etc. and you end up having to copy markup between all files. Horrid, unmaintable mess!

Django, Flask or whatever is hip now is still far too much, so you think:

I could simply separate content from structure if I just had templates…

Static site generators are supposed to come to help. Having never used them, I landed on this list by Full Stack Python.

While browsing through these, I had one thought — this is all so complex! I just wanted to quickly add some templates to my website, not to convert my stuff to a CMS.

I checked a few and finally found that mynt fits my criteria and allows me to build on the top of my HTML. So let’s have a try!

Conversion

Install mynt globally or in a virtual environment on your system using command pip install mynt.

All you need to do for mynt to recognise your site is to create a configuration file named mynt.yml. For now all we need to set is the URL to your assets directory – add assets_url: /assets. Adjust the URL if you want to serve them from somewhere else. See here for all the options.

You need to move your assets to a folder \_assets for them to be copied to /assets directory when the website is generated.

You can then generate a website: mynt generate \_build, or generate on every file change mynt watch —f . \_destination.

\_build will be just a raw copy of what you had earlier — the great thing about mynt is that you can consecutively use both your newly written, templated pages and the old stuff. let’s use the new abilities!

Templates

All directories beginning with an underscore are either special or ignored.

_templates is a directory where jinja2 — templating engine similar to the one used by Django — searches for templates to extend from.

Let’s say you already have an index.html just like this one:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!doctype html>
<html>
<head>
    <title>Home page — prem.moe</title>
</head>
<body>
    <nav><a href="/">Home page</a></nav>
    <main>
        Hello world!
    </main>
</body>
</html>

Since the reason to do templating is to re-use common structure, we’ll split this file into _templates/main.html and index.html. The template will look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!doctype html>
<html>
<head>
    <title>{{ title }} — prem.moe</title>
</head>
<body>
    <nav><a href="/">Home page</a></nav>
    <main>
        {% block content %}
        {% endblock %}
    </main>
</body>
</html>

And your new index.html:

1
2
3
4
5
6
{% extends 'main.html' %}
{% set title = 'Home page' %}

{% block content %}
Hello world!
{% endblock %}

Conclusion

And thus we have achieved separation of content from the structure — and adding new pages or changing common elements is trivial.

Since the page is static, all you need to do to publish it is to copy _build contents to your hosting which may be something as simple (and free) as GitHub Pages.

The next step to take is to take advantage of all the other features mynt provides — I in particular like posts and their tagging which can generate categories and archives based on your templates — this is such a post and you can click on the categories at the top to see what a category archive looks like.

Having a trivial template generate an Atom feed struck me as genius and showing the flexibility of the system. Have I mentioned syntax highlighting? For now that’s all I need!

Adding these will probably be a subject of the next entry. In the meantime — happy hacking!