Fundor333

New Render Image For Hugo


New Render Image For Hugo

2024-07-28 | dev fingerfood blog devops hugo module
Reading time 4 minutes | Word count 806 |

The story so far

Some time ago I wrote a post about lazy loading and WebP in Hugo 1 and how I implemented it.

When you add image in your Hugo’s site you also launch some script for some image optimization. Some problems come from the custom script for the build, were you need to have other code install in your machine or wherever you compile your static site.

It was a good implementation and a fast one but some time after I find a better way to implement better way to serve img in a static site, so I wrote a new article 2 where I describe the implementation with a “Hugo’s way” with a internal pipeline.

In this implementation I combine as find in a blog post 3 the srv html tag 4 in the picture tag 5 without the Avif format file6

I don’t like this way because it is inside the theme. I want to have this function like something I can import in any of my Hugo projects without copy and pasting the same code any time.

So I search for something like a package for Hugo so I find the Hugo Module

GoHugo Module

Hugo is write in GoLang so the dev implement a way to use a golang module as add-on for your Hugo site.

In my module Macia Image 7 I implemented a ‘partial theme’ which the only think it does is optimize the image of the posts like the one done for the second post 2

Code

So this is my code form the path layouts/_default/_markup/render-image.html in the theme from the old way 2 but now it is at the new path of the module layouts/_default/_markup/render-image.html where I build the images INSIDE the post.


{{/* Original code from: https://laurakalbag.com/processing-responsive-images-with-hugo/   */}}
{{/* Just modified a bit to work with render_image hook and output webp images   */}}
{{/* get file that matches the filename as specified as src=""  */}}
{{ $src := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL))  }}
{{ $alt := .PlainText | safeHTML }}

{{/* So for posts that aren't setup in the page bundles, it doesn't fail  */}}
{{ if $src }}

{{ $format := cond (eq $src.MediaType.SubType "gif") "" "webp" -}}

{{ $xs := .Page.Site.Params.maciaimage.tiny }}
{{ $s := .Page.Site.Params.maciaimage.small }}
{{ $m := .Page.Site.Params.maciaimage.medium }}
{{ $l := .Page.Site.Params.maciaimage.large }}

{{ $tinyw := default (printf "%s %s" $xs $format) }}
{{ $smallw := default (printf "%s %s" $s $format) }}
{{ $mediumw := default (printf "%s %s" $m $format) }}
{{ $largew := default (printf "%s %s" $l $format) }}

{{/* resize the src image to the given sizes */}}
{{/* We create a a temp scratch because it`s not available in this context */}}
{{ $data := newScratch }}

{{ $data.Set "tiny" ($src.Resize $tinyw) }}
{{ $data.Set "small" ($src.Resize $smallw) }}
{{ $data.Set "medium" ($src.Resize $mediumw) }}
{{ $data.Set "large" ($src.Resize $largew) }}

{{/* add the processed images to the scratch */}}

{{ $tiny := $data.Get "tiny" }}
{{ $small := $data.Get "small" }}
{{ $medium := $data.Get "medium" }}
{{ $large := $data.Get "large" }}

{{/* only use images smaller than or equal to the src (original) image size, as Hugo will upscale small images */}}


<a href="{{ $src.RelPermalink }}">
    <picture>

      <source media="(max-width: 376px)"
          srcset="{{with $tiny.RelPermalink }}{{.}}{{ end }}">

      <source media="(max-width: 992px)"
          srcset="{{with $small.RelPermalink }}{{.}}{{ end }}">

      <source media="(max-width: 1400px)"
          srcset="{{with $medium.RelPermalink }}{{.}}{{ end }}">

      <source media="(min-width: 1600px)"
          srcset="{{with $large.RelPermalink }}{{.}}{{ end }}">

      <img alt="{{ $alt }}" title="{{ $alt }}" src="{{ $src }}" loading="lazy" decoding="async" height="{{ $src.Height}}" width="{{ $src.Width }}" class="{{.Page.Site.Params.maciaimage.imgclass}}">

    </picture>
</a>

  {{/* Since I do image-response class, the only thing that really
  matters is the height and width matches the image aspect ratio */}}

  {{ end }}

In this code I set some values from the configs of the site so you can customize it in your theme and import it when ever you need it.

NB

This code, unlike the old one 2, support the Gif file format and output only file as WebP and a lot of them. As you can see in the script, the code generate 4 copy of the original image with 4 different image size (configurable in the config of the site).

When the Hugo’s Team add support for Avif3 I will add it into the module for generate all the image with the config setting which format image will be outputting.


  1. Fundor333 - Hugo With Lazy Loading and Webp  ↩︎

  2. Fundor333 - Generate WebP and AVIF with Hugo  ↩︎ ↩︎ ↩︎ ↩︎

  3. From Bennett Notes - Hugo Responsive Images With Markdown Render Hook  ↩︎ ↩︎

  4. Mozilla wiki - Src set  ↩︎

  5. Mozilla wiki - Tag HTML picture  ↩︎

  6. GitHub issue - Add image processing support for AVIF  ↩︎

  7. Macia (like the tea) is the name of all my Hugo’s module and Image for the scope of the project ↩︎

Mentions and response

Respond to this post on your own site. If you do, send me a webmention here.

Find out more about webmentions on the IndieWeb.