Page Bundle, relative image path in RSS feed wrong

Hey there,

I’m using Hugo with page bundles, so all my posts are located in paths like the following:

content/posts/2014-01-10-my-first-blog-post/index.md

In my index.md I reference images the following way: ![Some alt text](image.png), the images are just located in the same directory as the index.md. This has the nice side effect that I can see them in my markdown editor and this works fine for the website itself.

Unfortunately now I have the problem that these images don’t show up correctly in the RSS feed as there they are missing a part of the path:

<img src="image.png" alt="Some alt text">

For it to work it has to look like:

https://blog.example.com/posts/my-first-blog-post/image.png

My index.rss.xml template:

  <description>
    {{ .Content | html }}
  </description>

What’s the way to teach the index.rss.xml template to include the path of the post when linking to images?

For some reason I didn’t find many people with the same issue, maybe because page bundles are still new? If anyone could point me in the right direction I’d be very grateful!

Thanks!

Hi, it looks like the issue I have when I look at my page headers. I haven’t solved it yet…

When you look at the source code of your generated pages, are all the image URLs wrong in the meta headers?

Hey,

when I look into the generated feed (feed.xml) I see the images are linked like:

<img src="image.png">

In the generated page of the post itself they are also linked like:

<p><img src="image.png"></p>

But as it’s a relative path it works for the post as the image is in the directory of the post itself which is not the case for the feed which is one “level” higher in the directory structure of course.

Basically what I’m looking for is a way to inject the path of a post when the feeds gets generated. I’m not sure if that’s possible. I’d like to not use figure constructs in the post as then I can’t preview the picture in my markdown editor (iA Writer).

You can try this solution:

Interesting, thanks.

Unfortunately I couldn’t get it to work. Line 72:11 is the last one with return $html

hugo server -D
Built in 853 ms
Error: Error building site: failed to render pages: render of "home" failed: "/Users/blog.example.com/layouts/index.rss.xml:72:11": execute of template failed: template: index.rss.xml:72:11: executing "index.rss.xml" at <return>: wrong number of args for return: want 0 got 1


<description>
{{ $html := htmlUnescape .Content | safeHTML }}

{{ $hrefs := findRE "href=\"([^\"]*)\"" $html }}
{{ range $href := $hrefs}}
  {{ $absHref := strings.TrimPrefix "href=\"" $href  }}
  {{ $absHref = strings.TrimSuffix "\"" $absHref  }}
  {{ $absHref = printf "href=\"%s\"" ($absHref | absURL) }}
  {{ $html = replace $html $href $absHref }}
{{ end }}

{{ $srcs := findRE "src=\"([^\"]*)\"" $html }}
{{ range $src := $srcs}}
  {{ $absSrc := strings.TrimPrefix "src=\"" $src  }}
  {{ $absSrc = strings.TrimSuffix "\"" $absSrc  }}
  {{ $absSrc = printf "src=\"%s\"" ($absSrc | absURL) }}
  {{ $html = replace $html $src $absSrc }}
{{ end }}

{{ $srcset := findRE "srcset=\"([^\"]*)\"" $html }}
{{ range $set := $srcset}}
  {{ $parts := strings.TrimPrefix "srcset=\"" $set  }}
  {{ $parts = strings.TrimSuffix "\"" $parts  }}
  {{ $parts = split $parts "," }}
  {{ $newSrcset := slice }}
  {{ range $part := $parts }}
    {{ $part = $part | replaceRE "^\\s*(.*)\\s*$" "$1" }}
    {{ $lg := split $part " " }}
    {{ $href := index $lg 0 | absURL }}
    {{ $size := index $lg 1 }}
    {{ $newSrcset = $newSrcset | append (printf "%s %s" $href $size) }}
  {{ end }}
  {{ $newSrcset = delimit $newSrcset ", " }}
  {{ $newSrcset = printf "srcset=\"%s\"" $newSrcset }}
  {{ $html = replace $html $set $newSrcset }}
{{ end }}

{{ return $html }}

ahh, the OP actually use it inside partial.

replace:

{{ return $html }}

with:

{{ $html }}

Ah, well spotted! Thanks! I got it to work but then I have absolute links based on the baseURL and not the URL of the page bundles. The resulting URL is then:

blog.example.com/image.png instead of blog.example.com/my-blog-post-slug/image.png

It seems like this whole page bundle concept is not that well supported yet or am I misunderstanding something bigger there? Seems like a pretty basic feature to have images working across the whole Hugo site?

If I use the following it seems that it works across the feeds too, is that the suggested solution? I’d lose previewing in my markdown client but if that’s what’s necessary I guess that’s how it’s going to be.

{{< figure src="image.png" alt="some text">}}

AFAIK, yes using {{<figure>}} does the job.

If you really want to keep using markdown syntax to include your images. You can use Markdown Render Hooks. (Need to create your own render hook template).

Some related threads about image render hooks:

1 Like

Ah, that seems like a good solution I haven’t tried. I’ll give that a try in the next days. Thanks!

Came here through a search engine. An RSS-specific image render hook is working well for me, thanks @pamubay!

I put the following contents in layouts/_default/_markup/render-image.rss.xml:

{{/* Make sure to always use absolute image URLs in RSS feeds. */}}
{{- $srcUrl := "" -}}
{{- if or (hasPrefix .Destination "http://") (hasPrefix .Destination "https://") -}}
  {{ $srcUrl = .Destination }}
{{- else if hasPrefix .Destination "/" -}}
  {{ $srcUrl = absURL .Destination }}
{{- else -}}
  {{ $imageResource := .Page.Resources.Get .Destination }}
  {{- if $imageResource -}}
    {{ $srcUrl = $imageResource.Permalink }}
  {{- else -}}
    {{ $srcUrl = ref .Page .Destination }}
  {{- end -}}
{{- end -}}
<img src="{{ $srcUrl | safeURL }}" alt="{{ .Text }}" {{ with .Title }}title="{{ . }}"{{ end }}>

This passes absolute URLs with a protocol through as-is, resolves URLs starting with a / relative to the site base URL, and resolves relative URLs as resources in the page bundle before trying them relative to the page URL.

Parts of this are untested and I’m sure there is room for improvement, but this works for me, for now.