Simple image render hook template for responsive images

Thank you very much for the great Hugo 0.62.0 christmas present!

This simple image render hook template uses the image title as an optional caption.

Feel free to adjust and use, if this template fits your use case.

{{ $image := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL)) }}
{{ $small := $image.Resize "480x" }}
{{ $medium := $image.Resize "768x" }}
{{ $big := $image.Resize "1024x" }}
{{ $alt := .PlainText | safeHTML }}
{{ $caption := "" }}
{{ with .Title }}
  {{ $caption = . | safeHTML }}
{{ end }}

<figure>
  <a href="{{ $image.RelPermalink }}">
    <img
      sizes="100vw"
      srcset="{{ $small.RelPermalink }} 480w, {{ $medium.RelPermalink }} 768w, {{ $big.RelPermalink }} 1024w"
      src="{{ $image.RelPermalink }}"
      width="{{ $image.Width }}"
      height="{{ $image.Height }}"
      alt="{{ if $alt }}{{ $alt }}{{ else if $caption }}{{ $caption | markdownify | plainify }}{{ else }}&nbsp;{{ end }}"
      >
  </a>
  {{ with $caption }}
    <figcaption>{{ . | markdownify }}</figcaption>
  {{ end }}
</figure>

An addition on how to use this template:

Save the code published above to /layouts/_default/_markup/render-image.html as described here.

In your markdown content files use the regular images markdown code in order to render a responsive image:

![Alt should always be set for reasons of inclusion](my-image.jpg "An optional title/caption supporting *markdown*")

As mentioned this template uses the title attribute to produce a caption. Of course, you can (additionally) use it as usual.

16 Likes

This is great, appreciate seeing an example of a render-image.html template but I have my images all in the static directory (/static/images) and I use /images as the path for my images in markdown

![Duncan holding a big bird](/images/yes-that-is-a-big-bird.jpg)

I’m trying to figure out how to get the height/width of this image at build time so that I can add it to my img tag, but no luck so far :frowning:

Any ideas?

Hi!

Glad to hear this.

You can move your images folder e.g. to /content/images/ as described in this post. You can skip step 3 and optionally step 4.

Hope this helps.

tried this but $.Site.GetPage (loking for image directory inside content eg: content/uploads) throw an error. is it won’t work in render hook, or am i missed something here?

Hi! I don’t quite understand how you are using $.Site.GetPage. Could you share your code?

Normally you just need to create /content/images/, and then you can use the code above like this:

![Alt text](/images/test.jpg)

Edit: Oh I see—you were referring to this article. To get the image render hook shared above to work, you can simply skip steps 3 and 4. The render hook replaces step 4 so to speak.

It seems like $.Site.GetPage is not supported in render hooks. It is needed for Forestry to look up the resource in the content folder and not in a page bundle.

You can do either

  • $.Page.Site.GetPage
  • site.GetPage
1 Like

What you can do is to move (or mount) your /images folder to /assets, and then do something ala this:

3 Likes

Is it worked for webp and svg images?

I just use it, but got an error.

Built in 2865 ms
Error: Error building site: "/home/dian/blog/petanikode/themes/kacang/layouts/_default/_markup/render-image.html:22:18": execute of template failed: template: _default/_markup/render-image.html:22:18: executing "_default/_markup/render-image.html" at <$img.Resize>: error calling Resize: *resources.genericResource is not an image

No, it does not.

To make the code shown above work with SVG I use something like this. I did not want to make the shortcode to complex:

{{ if in (.Get "src") "svg" }}
  <figure>
    {{ $svg := .Page.Resources.GetMatch (.Get "src") }}
    {{ $svg.Content | htmlUnescape | safeHTML }}
    {{ with .Get "caption" }}
      <figcaption>{{ . | $.Page.RenderString }}</figcaption>
    {{ end }}
  </figure>
{{ else if $image }}
 {{/* code as shown in the initial post */}}
{{ end }}

Yet, I never tried to get it to work with webp.

1 Like

about scaling svg: