Paginated Posts With Hugo

March 9, 2023

Media Woes

Yeah, references to any media in the bundle is where you’re going to run into your first hurdle. For example, consider markdown like this on, say, page 2:

![some title](some-image.jpg)

The image, some-image.jpg, is presumably located in the same directory with all your page content. Unfortunately, this is not going to work; it will be translated into HTML roughly similar to this:

<img src="some-image.jpg" alt="some image">

Perfectly valid, right? Except that it’s a relative path. It’ll work on the first page of your document, but subsequent pages are going to fail to find the image. Why? Because Hugo rendered your page as /my-blog/my-document-slug/page/2/.

Your image is not in that directory; it’s a couple of levels up.

So what do we do now?

Media Management

The simplest way to deal with it (in my opinion) is to avoid direct Markdown syntax for images. Hugo offers shortcodes for our convenience, and that is where the answer lies. So for example, instead of the above markdown, you might call a shortcode like this:

{{% post-image src="some-image.jpg" title="some title" %}}

Your shortcode can then “do the right thing” to display the image. It’s actually a fairly simple shortcode implementation in the extremely basic case:

{{- $src   := .Get "src"   -}}
{{- $title := .Get "title" -}}
{{- img    := .Page.Resources.Get $src | default .Page.Parent.Resources.Get $src -}}
<img src="{{ $img.RelPermalink }}"{{ with $title }} alt="{{ . }}"{{ end }}>

And that’s it. It will chase up the chain to find the correct resource, and use that resource’s RelPermalink to link it correctly. This technique can also be used to access any other type of resource you may need from within the post.

In my case, I was lucky; I was already using a shortcode for images to handle things that WordPress allowed, like alignment on the page. Adding this to it was fairly trivial in my case.

So now that media is done, what else is going to bite us?