Hugo

Relative image links with page bundles broken on main page

I’m using page bundles, with a directory structure like this:

content/
├── about
│   ├── index.md
├── posts
│   ├── my-post
│   │   ├── content1.md
│   │   ├── content2.md
│   │   ├── image1.jpg
│   │   ├── image2.png
│   │   └── index.md

When I link to an image in a post, I use a relative path:

![Image](images/foo.jpg)

This works great for the post itself, but when the post is displayed on the main index page, which has a list of recent posts, the image URL is broken, because the relative path is no longer correct. How can I fix this?

Hello,

The info you provide is not enough. At the very least we need to see how you reference the image resources for each post from the index page template.

I’m using the default template that comes with the theme Hugo-Flex, which is just:

{{ define "preload" }}

{{ where .Pages "Type" "in" site.Params.mainSections | .Paginate | .Scratch.Set "paginator" }}
{{ range (.Scratch.Get "paginator").Pages }}
{{ with .Content }}{{ end }}
{{ .Scratch.Get "css" | $.Scratch.Set "css" }}
{{ .Scratch.Get "js" | $.Scratch.Set "js" }}
{{ end }}

{{ end }}

{{ define "main" }}

{{ range (.Scratch.Get "paginator").Pages }}
<article>
  {{ partial "heading.html" . }}
  {{ .Content }}
  {{ partial "tags.html" . }}
</article>
{{ end }}
{{ .Scratch.Get "paginator" | partial "pagination.html" }}

{{ end }}

So I guess the problem is the relative image links in {{ .Content }} need to be changed somehow. How can I do this?

Using just .Content will never render these images in list pages.

Please have a look at the Image Resource Method in the Docs:

and the Page Resources Doc:

Hello, thanks for the reply. I’ve already read those doc pages, but neither of them solves the problem of relative image paths. I would like to know how other people have solved this problem. Do they use a regexp to replace all the relative paths with absolute paths?

A resource for example is called within the Pages range by using:

{{ with .Resources.ByType "image" }}
{{ $original := . }}
<img src="{{ $original.RelPermalink }}" alt="whatever">
{{ end }}

The Page Resources images are not part of the .Content variable.
Most people here create shortcodes for their Page Resources images that can be used in the order that is needed within the content file.

There are examples right here in the forum (use the search button) and in the docs.

Also I recommend that you check out a theme that uses Page Resources. The one you use currently doesn’t.

Thank you, the key word “shortcode” was what I was missing. I found a good overview of using shortcodes to embed images within content here.

Reposted here for posterity:

# layouts/shortcodes/img.html
{{ $img := $.Page.Resources.GetMatch (printf "images/%v" (.Get 0)) }}
{{ with  $img }}
<figure>
	<img src="{{ .RelPermalink }}" alt="{{ .Get 1 }}" />
	<figcaption>{{ $.Get 1 }}</figcaption>
</figure>
{{ end }}

Markdown:

{{< img "*overcooked-dough*" "Those cupcakes are way overcooked!" >}}

Edit: Modified the shortcode to actually work, there were a couple issues with the code from the blog post.

1 Like

I hear what @onedrawingperday suggests about using a theme with that calls the Pages range.

That said, I like the way the Hugo Flex theme otherwise structures content, and I’d invested too much time in customizing its appearance with my own CSS to readily abandon it for another theme.

So… I’d had the same problem as @agargara. I could not figure out how to get relative links to generate differently for the main page.

Here is my solution, for anyone who runs into this problem in the future.

First, my content is organized using page bundles. For example:

The a-peculiar-form-of-torment folder represents my first post.

I then created my own shortcode, named figure.html. Here’s what it looks like (I’m overriding the core Hugo figure shortcode):

{{ $imgname := .Get "imgname" }}
{{ $title := .Get "title" }}
{{ $caption := .Get "caption" }}
{{ $alttext := .Get "alt" }}
{{ $width := .Get "width" }}
{{ $height := .Get "height" }}
{{ $img := $.Page.Resources.GetMatch $imgname }}
<figure>
	<img src="{{ $img.Permalink }}" alt="{{ $alttext }}" width="{{ $width }}" height="{{ $height }}"/>
	<figcaption>
		<h4>{{ $title }}</h4>
		<p>{{ $caption }}<p>
	</figcaption>
</figure>

Here’s what it looks like when I use that shortcode from my content file, index.mmark in the a-peculiar-form-of-torment folder:

{{< figure imgname="boards-joined.jpg" caption="A strong join between the boards is helpful to be certain they remain perpendicular." alt="Angle irons are used to join the two boards together at a 90-degree angle." width="169" height="200">}}

You can see that in this case, I chose to omit the title attribute.

The image will then render regardless of whether the user is on the “main” or landing page of my Hugo site, running the Hugo Flex theme, or whether the user reads the article through the Archive, where I collect my posts.

Finally, I also have the baseURL parameter set in my config.toml file, like this:

baseURL = "https://russellgordon.ca"

All of this works through the use of permalinks, but if anyone with more knowledge than I can clearly describe how to make this work using relative links, I’d love to learn how.