Cache busting with resources.Concat

I found this trick on this forum to rename processed images with resources.Concat. However, I was wondering what’s the best function to use that can bust the cache in case the processed image is changed, and preferably one with a short string. Anyone with an idea?

{{- with $img -}}
{{- $tinywebp := .Resize "600x webp" -}}
{{- $smallwebp := slice $tinywebp | resources.Concat ( printf "%s-%v%s" (strings.TrimSuffix (path.Ext .RelPermalink) .RelPermalink) (<!-- cache busting func goes here -->) (path.Ext .Name)) -}}
<!-- image code here -->
{{- end }}

I’m not sure that I understand. In this context, .RelPermalink already has a cache buster in its name.

{{ with .Resources.Get "cover.jpg" }}
  {{ with .Resize "300x" }}
    {{ warnf "%s" .RelPermalink }}
  {{ end }}
{{ end }}
/posts/post-1/cover_hu7ea6bbdd4d289c929adf1f5f39c46d1e_158382_300x0_resize_q75_box.jpg
              -----   -------------------------------- ------ ------------------------
                A                        B                C              D

A: Changes if you change the image file name
B: Changes if you change the image content
C: Changes if the image file size changes
D: Changes if you change the image processing parameters

Also see documentation for resources.Copy.

The result of my code above without the middle part (%v) is image-path/image-name.jpg. But I need it to be image-path/image-name-(random short number).jpg. I hate the way Hugo renames processed images, hence my need to change the way the images are named in the render hook.

I know about resources.Copy, but I am not knowledgeable enough to code a solution that renames every image in the render hook in the format I desire above.

Closest I have come to a short number is using crypto.FNV32a with the image width, but I know that will not change once the images are processed afresh. now.Unix I don’t know if it will refresh the image on every build, though it works too.

This is a very simple image render hook that ignores a lot of things like remote URLs, images in the assets directory, title attribute, etc. It just demonstrates the resources.Copy approach, nothing else.

markdown

![kitten](kitten.jpg)

layouts/_default/_markup/render-image.html

{{ with .Page.Resources.Get .Destination }}
  {{ $targetDir := path.Dir .Key }}
  {{ $targetBaseName := path.BaseName .Key }}
  {{ $targetExt := path.Ext .Key }}
  {{/* Do whatever image processing you need here. For example, resizing. */}}
  {{ with $r := .Resize "300x" }}
    {{ $targetPath := printf "%s/%s-%d%s" $targetDir $targetBaseName (.Key | crypto.FNV32a) $targetExt }}
    {{ with resources.Copy $targetPath . }}
      <img src="{{ .RelPermalink }}" width="{{ $r.Width }}" height="{{ $r.Height }}" alt="{{ $.PlainText }}">
    {{ end }}
  {{ end }}
{{ end }}

rendered HTML

<img src="/posts/post-1/kitten-302475903.jpg" width="300" height="200" alt="kitten">

published files

public/
├── posts/
│   ├── post-1/
│   │   ├── index.html
│   │   ├── kitten-302475903.jpg
│   │   └── kitten.jpg
│   └── index.html
├── favicon.ico
└── index.html

I just edited the above to prevent publishing of the intermediate image(s).

What if I want to include more image sizes (webp), and use figure? How will that code look like?

As they in tutorials, that is “left as an exercise for the reader.” You’ve got the basic mechanics above.

I went back to using my method above with the crypto stuff. I will still mark your answer for anyone else interested.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.