I posted Tweaking a Nikola Theme on Saturday, 25 January, 2020

Tweaking a Nikola Theme
The /now page, in Nikola
Post nikola site

Tweaking a Nikola Theme

I adjusted the default Nikola theme to show cover images!

Motivation

I am a visual person. You might not know that from all the typing and my enthusiasm for command line tools. But many of my posts and pages have cover images. Sometimes the cover images are even relevant to the post.

In the live site, cover images are prominently displayed at the top of their pages. They get referenced when a post gets shared on social media. A cropped and adjusted version of the cover image gets displayed in post summaries.

So if I’m using Nikola to build something like my current site, I need cover images.

Nikola site uses the bootblog4 theme by default, taking advantage of the Bootstrap toolkit. bootblog4 doesn’t support cover images, so I’ll make a version that does.

Mind you, I don’t want to build a whole new theme. That can come later. There’s even a nice tutorial for creating a theme. For now I just want to tweak the default a little.

Set up files and metadata

Nikola starts with a few assumptions I can work with. bootblog4 already looks for previewimage metadata to build thumbnails for featured posts. Nikola also expects to find image files in your site’s images/ folder. Makes sense.

I’ll mirror the content path with images, and add previewimage metadata which points to the right spot.

posts/2019/12/again-with-the-manual-symmetry/index.md
---
date: 2019-12-15 12:37:51-08:00
tags:
- drawing
- Procreate
- symmetry
title: Again with the manual symmetry
category: note
previewimage: /images/2019/12/again-with-the-manual-symmetry/cover.jpg
---

Hugo uses a powerful but sometimes confusing taxonomy system in layout customization. Nikola prefers a powerful but sometimes confusing "theme inheritance" system. Look. They’re all confusing. It’s just a matter of finding the kind of confusing you don’t mind.

With theme inheritance, my tweaks are a new theme. But the new theme basically says "I’m like that theme, except that I changed these templates."

So let’s inherit a theme.

Nikola’s theme command

OptionDescription
-i ARG, --install=ARGInstall a theme. (config: install)
-r ARG, --uninstall=ARGUninstall a theme. (config: uninstall)
-l, --listShow list of available themes. (config: list)
--list-installedList the installed themes with their location. (config: list_installed)
-u ARG, --url=ARGURL for the theme repository (default: https://themes.getnikola.com/v8/themes.json) (config: url)
-g ARG, --get-path=ARGPrint the path for installed theme (config: getpath)
-c ARG, --copy-template=ARGCopy a built-in template into templates/ or your theme (config: copy-template)
-n ARG, --new=ARGCreate a new theme (config: new)
--engine=ARGEngine to use for new theme (mako or jinja – default: mako) (config: new_engine)
--parent=ARGParent to use for new theme (default: base) (config: new_parent)
--legacy-metaCreate legacy meta files for new theme (config: new_legacy_meta)

So I ask Nikola for a new theme, using bootblog4 as the parent.

$ nikola theme --new rgb-bootblog4 --parent bootblog4
...
[2020-01-21T15:35:33Z] NOTICE: theme: Remember to set THEME="rgb-bootblog4" in conf.py to use this theme.

Because I didn’t specify a template engine, rgb-bootblog4 uses Mako.

Let’s remember to update conf.py as directed, so we can see the theme as we tweak it. The theme tutorial also mentions disabling USE_BUNDLES during theme development. I thought they meant page bundles for a second and got excited, until I realized bundles meant bundled JavaScript and CSS for quicker HTTP/1 downloads.

# Name of the theme to use.
THEME = "rgb-bootblog4"

USE_BUNDLES = False

Sweet. I have a new themes/rgb-bootblog4 folder. Wait. It has no templates.

Oh that’s right. This is what they were talking about with template inheritance. The templates are still in the parent. It’s up to me to copy and change specific templates. That’s both good and a little risky when the parent theme updates. What if my tweak turns out to be incompatible? Okay, not going to worry about it today. If you’re going to veer wildly from the parent, you should probably use base as the parent.

Editing templates

So which of the built-in templates do I want? Since both posts and pages have cover images on my site, I’ll start with the most general template. Everything starts with base.tmpl. Let’s look there.

$ nikola theme -c base.tmpl

Can I find anything interesting in the base template?

⋮
${template_hooks['page_header']()}
<%block name="extra_header"></%block>
<%block name="content"></%block>
⋮

Over here on the live site, I put cover images above the main content. extra_header looks promising. Where to set it? I prefer to make my changes in the most relevant template instead of the most general.

Give me a minute to explore…

Okay. Pages ultimately inherit from posts — Mako supports template inheritance, letting the parent define some blocks while overriding others. We might be able to do this with one change.

$ nikola theme -c post.tmpl

Nikola provides a large number of template variables to work with, but today I focus on post. How about the preview image? It gets set in post metadata, so I could use post.meta("previewimage"). Don’t have to do that though. previewimage metadata is important enough that it gets promoted to an attribute of the post object.

post.tmpl
<%block name="extra_header">
  % if post.previewimage:
      <div class="figure">
          <img src="${post.previewimage}" alt="${post.title}" width="1000">
          <p class="caption">${post.title()}</p>
      </figure>
  % endif
</%block>

Keep in mind what I noticed the other day about these not being real figures in reStructuredText. For now I match RST output, as if I’d used a figure directive. That way I don’t have to find the CSS for this theme.

Cover image in a post
Figure 1. Cover image in a post

It has a cover image, placed right by the title. It doesn’t quite match today’s view of that post, but this has the basic idea. And I only had to edit a single template file!

same post on live site
Figure 2. The same post on the live site

Looks good for posts that have a cover image. How about pages?

cover image in page
Figure 3. Cover image in a page

Excellent. I thought that would take much more work.

Remember Bootstrap?

bootblog4 is based off of Bootstrap. I feel compelled to make the cover image a Jumbotron.

<%block name="extra_header">
  % if post.previewimage:
      <div class="figure jumbotron">
          <img src="${post.previewimage}" alt="${post.title}" width=1000>
          <p class="caption">${post.title()}</p>
      </div>
  % endif
</%block>
cover image in jumbotron
Figure 4. Cover image in Bootstrap Jumbotron

Hm. Maybe, maybe not. I’m tempted to tweak it some more, but my task list is long and my time is short.

Did I miss anything?

Sort of. On the live site, I let Hugo resize cover images to fit in my design and avoid large downloads. Nikola has thumbnails, but that’s not quite the same thing. I’d have to do it myself, maybe with a plugin.

Indieweb Social

Did you mention this somewhere? I'd love it if you sent me the link!

disclaimer about timing

Mentions are sent to webmention.io. I fetch the latest mentions when building the site, so I may not see your feedback right away. Especially if my site's broken, which is often the case.

Public replies and mentions might be shared on the site, but I try to do a little quality check first.

Site Links