marten

From Jekyll to Nikola

I have recently moved my website from Jekyll to Nikola, another static site generator. The main reason was that I wanted to move from ruby to a python solution because I have pretty much stopped using ruby since I left my side job. In university python is my language of choice anyway because of its math and plotting libraries, so it makes sense to use it for scripting and my website, too.

With this premise I put my favorite search engine to work and found loads of options but decided quickly for Nikola, mainly to avoid analysis paralysis. Its first big plus is that it supports restructuredText out of the box which I wanted to learn for a long time. It always seemed superior to markdown with its extensible roles and directives, for example the math directive for LaTeX formulas. Speaking of which Nikola has built-in support for rendering LaTeX math in posts with MathJax which was actually also one of my exclusion criteria in the first place. However, I quickly replaced MathJax with KaTeX since it is noticeably faster – read jerking page motions as each equation is rendered versus subsecond rendering of the whole page – and I believe that its reduced instruction set will suffice for me. Finally, I am thrilled to put jupyter notebooks directly on my page at some point.

The main disadvantage in comparison to Jekyll that I discovered is that theming is harder. Jekyll is pretty bare-bones in that regard and you necessarily have to do everything yourself which has the upside of giving you full control from the beginning. Nikola on the other hand comes with core- and community-developed themes with a certain structure. This can get you going fast but as soon as you want to customize your page, you find yourself writing your own theme. The process is only barely documented and in the end I copied and modified the lanyon theme which was ironically ported from Jekyll, among other things translating it from Mako to Jinja2 that I already knew from ansible. Additionally I prefer its brace syntax over Mako's XML language.

My most invasive change to the lanyon theme is the listing of categories and tags in the sidebar. The issue is that Nikola mostly consists of plugins, including a plugin for rendering a categories and tags page. This has the side effect that the list of categories and tags is only available on that particular page. So right after modifying my first theme I had to jump into Nikola's (admittedly somewhat messy) codebase to find out how I could make this work. In the end I wrote the following mini-plugin to make the categories and tags available on every page.

from nikola.plugin_categories import ConfigPlugin

class Tagsandcats(ConfigPlugin):
    def set_site(self, site):
        super().set_site(site)

        def registervars(context, template_name):
            tags = site.tags_per_language[site.default_lang]
            cats = site.category_hierarchy

            context["tags"] = [(tag, site.link("tag", tag)) for tag in tags]
            context["categories"] = [(cat.name, site.link("category", cat.name))
                                     for cat in cats]

        site.config["GLOBAL_CONTEXT_FILLER"].append(registervars)
Want to comment or get in touch? @martenlienen or email me