A new Hugo theme
My site is built using Hugo. Hugo has a wide range of themes available, which you can browse and preview at their theme gallery. So which Hugo theme am I using? None.
How Hugo themes work
Hugo is really two stacked things:
- The plumbing: content model, Markdown/org rendering, taxonomies, pagination, RSS/sitemap/robots (these are internal Hugo templates, free), the asset pipeline, fast rebuilds, and (in my case) the ox-hugo bridge from org-mode.
- The theme: just layout templates. The style.
Instead of creating a true custom theme, which is a full package that could be shared on Hugo’s theme page (and would need to be indefinitely maintained and guaranteed portable), I’m taking a different route, and I’m explaining it here in case someone (you) might want to adopt the same plan for your own site.
This current “theme”
My plan hinges on one aspect of Hugo’s functionality: the local
project-root layouts/ overrides the theme’s layouts/. This means
you can write your own templates one file at a time while the theme
stays installed, and each file silently takes over that page type. You
also don’t need a template for every page type - Hugo has a fallback
chain, and the minimal complete set is just _default/baseof.html,
_default/single.html, _default/list.html, index.html, and
404.html.
Start with those, and then each other component of the layout can be
replaced, one by one, tweaking to the result you want on your own
site. Eventually, when every single thing has been replaced, you can
just delete the entire theme line from hugo.toml. At that point,
everything is coming from your own collection of layout files, and
they form your custom theme.
A true theme is more than just layouts, it can inject assets/,
static/, default params, i18n/, and archetypes/. Those still merge
even when the layouts are fully shadowed. So if you don’t want those
from the theme, you will need to do the full removal, deleting that
theme line from hugo.toml. And to get there, you need your own
templates covering every page type your site actually produces - not
necessarily every template the theme ships, since it probably includes
layouts for page types you’ll never use.
So here’s my basic workflow in creating this current “theme”:
Start with a basic theme. The more complete the theme, the more of
your site’s behavior hides inside the theme’s files instead of yours -
so when you finally remove it, you’ll discover it was doing more than
you realized. I started with hugo-bearcub. I tweaked each aspect of
the theme using my own file in layouts/ until I no longer needed
that theme, and I deleted the theme = 'hugo-bearcub' line in
hugo.toml.
You might expect at least one surprise when you do. In my case the
theme had been quietly supplying robots.txt - with a Sitemap: line
in it - and Hugo’s built-in version has neither. Nothing looked
broken, because nothing looked like anything; it was a file I’d
never written and didn’t know I was relying on. Part of the argument
for doing the removal instead of just shadowing the layouts and
calling it done.
Then I browsed around Hugo’s theme gallery for the more feature-rich
themes, looking for specific things I’d want to incorporate into my
own site. When I found something, I edited/created a file in my own
project-root layouts/ directory, and magically that
feature/component shows up in my own site.
Hope that’s helpful for anyone wanting to get a custom look on their Hugo site.