Fun with Hugo themes


One of the challenges with Hugo is that, out of the box, it doesn’t do anything. Create a site, fill it with content, run the generator, and you get… nothing. You need to download or create a theme in order to actually render your content; there isn’t one built into the site-creator, although several volunteers are working on something (much the same way that usable documentation is largely a volunteer effort).

It is not immediately obvious that the theme gallery is sorted by update date, so that the farther down the list you go, the less likely they are to work. There’s a top-level set of feature tags, but they’re applied by the theme authors, and don’t include useful things like “scales beyond 100 pages”.

As part of my ongoing MasterCook molesting, I decided to take the now-sane XML files and render them to Hugo’s mix of TOML and Markdown, generating a static cookbook site with sections and categories. Having done some experimentation in response to a forum post, I knew that a site with 56,842 pages would take several minutes to build, so I grabbed the simple, clean Zen theme and fired it off.

And waited. And waited. And watched the memory usage climb to over 40GB of compressed pages.

The Hugo developers pride themselves on rendering speed, but when I checked the disk, it was taking upwards of a second to render a single content page. Looking at one of them made it obvious why: the theme designer included every content page in the dropdown menus and sidebar. It had honestly never occurred to him that someone might have more than about 8 categories with about 20 pages each. In fairness, this is a port of a Drupal theme, and the original might have had the same problem.

After modifying the templates to only use the first 20 from each category, I got the site to render in about 10 minutes. The category menu looks horrible, because I split the recipes up alphabetically into chunks of about a thousand, and the theme only allocated enough space for about 2/3 of them, with the rest covering the title field. The actual recipe rendering is excellent, including the handling of sub-recipes and referenced recipes.

I could modify the Zen theme until it did everything right, or spend several hours rebuilding a small sample site with other themes until I found one that required less work, but once you’ve built one theme from scratch, it’s just faster and easier to do that than to try to use any of the pre-built themes. Their real value is as examples of “how do you do this in Hugo”, which you can’t generally find in the documentation.

There are also quite a few working code snippets in the forums (some provided by me; problem-solving is kinda my thing, if you haven’t guessed by now), but with so much of the code under active development, any forum example more than a few months old is likely to be wrong now.

It’ll be a while before I bring the cookbook back up, since this is definitely a copious-free-time project, and not only do I have to knock together a theme and set up search (most likely Xapian Omega again, since I’m fresh on it), but also molest the recipe data and impose some consistency on categorization, tagging, and ingredient naming. Currently it has 782 distinct categories, many of which differ by only a few characters, and about 2/3 of them should really be tags instead. All of these issues should really be fixed in the MX2 files, so that they can be cleanly imported back into MasterCook, but since that’s not XML, the scripting is a little more “interesting”.

Tentatively, I’m going to start with my blog theme, since I’ve already tested it at scale (and learned that large taxonomies are a significant bottleneck). I can strip out a lot of the blog-specific stuff without much effort, I’ve already done the work to switch over to dropdown menus for categorization, so the only real trick will be embedding any referenced recipes in a hidden DIV at the bottom of each page, and setting up a print-only stylesheet that hides the nav and exposes the embedded recipes. The references are already turned into links to the appropriate recipe’s page, thanks to the builtin relref shortcode.


Comments via Isso

Markdown formatting and simple HTML accepted.

Sometimes you have to double-click to enter text in the form (interaction between Isso and Bootstrap?). Tab is more reliable.