Summary using images from page bundles

I’ve setup some simple blog posts using markdown and page bundles. The published version of the posts themselves shows working images. When I use manual summary splitting, the image links in the summary do not reference the published images. Is this expected behavior?

Please post the markdown that includes the image reference.

content/posts/2017-4-12-context-free
contains
index.md
Logo_1000.jpg

The markdown files contains the following directly after the front mater:

![Context Free Logo](Logo_1000.jpg)

By default, that markdown is rendered to:

<img src="Logo_1000.jpg" alt="Context Free Logo">

The URL does not begin with a slash, so it is relative to the content page. And that’s fine, when you are viewing the content page.

But when you render that HTML in a summary on a list page, the URL is now relative to the list page, so the image cannot be found.

You have three options.

Option 1 - Provide an absolute URL

![Context Free Logo](/posts/post-1/Logo_1000.jpg)

This is the easiest option, but it is also the most fragile. The links will break if you rename the directory, add permalink settings in site configuration, serve the site from a subdirectory, etc.

Option 2 - Use a shortcode to resolve the path

For example, override the built-in relref shortcode so that it resolves pages, page resources, and global resources.

layouts/shortcodes/relref.html
{{- $u := urls.Parse (.Get 0) }}
{{- if $u.IsAbs }}
  {{- $u.String }}
{{- else }}
  {{- with or (.Page.GetPage $u.Path) (.Page.Resources.Get $u.Path) (resources.Get $u.Path) }}
    {{- .RelPermalink }}
  {{- else }}
    {{- errorf "The %s shortcode was unable to find %s. See %s" .Name $u.Path .Position }}
  {{- end -}}
{{- end -}}

Then call the shortcode from your markdown:

![Context Free Logo]({{< relref "Logo_1000.jpg" >}})

This works well, but (a) it’s a pain to type, and (b) it’s not portable to other systems (e.g., the image will not appear when viewing the markdown page on GitHub).

Option 3 - Use a render hook

This is the best option:

  • The resulting URLs are always right, regardless of configuration changes, renaming the parent directory, etc.
  • The resulting URLs are portable
  • You can reference any resource: page, global, or remote
  • You can insert width and height attributes automatically
  • You can configure it to throw an error or warning when the image cannot be found
  • And much, much more

Here’s something to get you started. Place it the path shown below.

layouts/_default/_markup/render-image.html
{{- /* Determine content path for error messages. */}}
{{- $path := "" }}
{{- with .Page.File }}
  {{- $path = .Path }}
{{- else }}
  {{- $path = .Path }}
{{- end }}

{{- /* Get image resource. */}}
{{- $u := urls.Parse .Destination }}
{{- $r := "" }}
{{- if $u.IsAbs }}
  {{- with resources.GetRemote $u.String }}
    {{- with .Err }}
      {{- errorf "Unable to get remote image %s: %s. See %s" $u.String . $path }}
    {{- else }}
      {{- /* Image is a global resource (remote). */}}
      {{- $r = . }}
    {{- end }}
  {{- else }}
    {{- errorf "Unable to get remote image %s. See %s" $u.String $path }}
  {{- end }}
{{- else }}
  {{- with .Page.Resources.Get $u.Path }}
    {{- /* Image is a page resource. */}}
    {{- $r = . }}
  {{- else }}
    {{- with resources.Get $u.Path }}
      {{- /* Image is a global resource (local). */}}
      {{- $r = . }}
    {{- else }}
      {{- errorf "Unable to get image %s. See %s" $u.Path $path }}
    {{- end }}
  {{- end }}
{{- end }}

{{- if $r }}
  {{- /* Set image element attributes. */}}
  {{- $attributes := dict "src" $r.RelPermalink "width" (string $r.Width) "height" (string $r.Height) }}
  {{- with .PlainText }}
    {{- $attributes = merge $attributes (dict "alt" .) }}
  {{- end }}
  {{- with .Title }}
    {{- $attributes = merge $attributes (dict "title" .) }}
  {{- end }}

  {{- /* Render image element. */ -}}
  <img
    {{- range $k, $v := $attributes }}
      {{- printf " %s=%q" $k $v | safeHTMLAttr }}
    {{- end -}}
  >
{{- end -}}

2 Likes

Thank you!

But, I’m a bit bewildered: sounds like it’s impossible to use markdown, with a standard markdown image ref, that works out of the box with Hugo.

My goal is to write simple markdown that renders properly in most any markdown editor, that will also publish. (I’m ignoring the fact that many editors won’t understand the front matter. Which is reasonable and fine.)

I will attempt your 3rd option and write up if it works out.

Thank you again!
Jason

1 Like

Yeah, there’s some discussion about this…
https://github.com/gohugoio/hugo/issues/10585

By themselves, markdown renderers (Goldmark, Blackfriday, etc.) are dumb. They translate one thing to another thing, regardless of context. Imagine what would happen if translators at the United Nations did the same thing.

The relref shortcode and image/link render hooks intercept/bypass the markdown renderer, producing the correct links regardless of context.

Getting this to work out of the box is easy. Getting this to work out of the box without affecting existing sites is more complicated.

Yup. I get that changing these of features have cascading effects, and I appreciate your help. I was just feeling like I was missing something very obvious.

1 Like

A post was split to a new topic: Images relative to a page bundle