DEV Community

Christian Specht
Christian Specht

Posted on • Originally published at christianspecht.de on

Hugo/Lightbox image gallery: Renaming processed images

After the last post, I thought I was finished with my Hugo/Lightbox image gallery, but there was one more thing I didn’t like: the filenames generated by Hugo’s image processing.

As a reminder, my current image gallery shortcode (including image captions from EXIF data and overlaying images with a logo) looks like this:

{{ $logo := resources.Get "img/overlay-logo.png" }}
{{ $image := (.Page.Resources.ByType "image") }}
{{ with $image }}
    {{ range . }}
    {{ $resized := .Fill "150x115 q20" }}
    {{ $x := sub .Width (add $logo.Width 10) }}
    {{ $y := sub .Height (add $logo.Height 10) }}
    {{ $withlogo := .Filter (images.Overlay $logo $x $y)}}
    <a href="{{ $withlogo.Permalink }}" data-lightbox="x" data-title="{{ with .Exif }}{{ .Tags.ImageDescription }}{{ end }}"><img src="{{ $resized.Permalink }}" /></a>
    {{ end }}
{{ end }}

Enter fullscreen mode Exit fullscreen mode

Both the thumbnail ($resized) and the main image ($withlogo) are created with Hugo’s image processing features, which means that their final filenames are assigned at build time by Hugo, and they are ugly.

For example one of the images from my demo project: the original filename is notebook.jpg, but the the shortcode shown above produces this HTML:

<a href="http://localhost:1313/galleries/gallery1/img/notebook_hu3d03a01dcc18bc5be0e67db3d8d209a6_1586565_filter_6003090614434618376.jpg" data-lightbox="x" data-title="">
    <img src="http://localhost:1313/galleries/gallery1/img/notebook_hu3d03a01dcc18bc5be0e67db3d8d209a6_1586565_150x115_fill_q20_box_smart1.jpg" />
</a>

Enter fullscreen mode Exit fullscreen mode

1. The easy part: renaming the main image

Starting with version 0.100.0, Hugo supports renaming files after processing them, via resources.Copy.

Unfortunately, there aren’t many examples out there yet. The only one in the docs (resources.Copy "images/mynewname.jpg") doesn’t help me, because it uses a fixed filename, and I need dynamic filenames because I’m dealing with lists of images.

But this one case is easy: I want to give the processed image its original filename back, the one that it had before processing.

As I’m looping all images anyway and processing each one in the loop, the original filename with its complete path, which resources.Copy needs, is still accessible via .RelPermalink.

(. is the current image)

So it’s just a matter of changing this line:

{{ $withlogo := .Filter (images.Overlay $logo $x $y)}}

Enter fullscreen mode Exit fullscreen mode

…to this:

{{ $withlogo := .Filter (images.Overlay $logo $x $y) | resources.Copy .RelPermalink }}

Enter fullscreen mode Exit fullscreen mode

As always, here’s the commit with the changes in the demo project.

The resulting HTML now looks like this:

<a href="http://localhost:1313/galleries/gallery1/img/notebook.jpg" data-lightbox="x" data-title="">
    <img src="http://localhost:1313/galleries/gallery1/img/notebook_hu3d03a01dcc18bc5be0e67db3d8d209a6_1586565_150x115_fill_q20_box_smart1.jpg" />
</a>

Enter fullscreen mode Exit fullscreen mode

Already better than before, but the thumbnail still has an ugly filename.


2. The not-so-easy part: renaming the thumbnail

In past image galleries, I had used a suffix like _t for the thumbnails’ filenames, e.g. notebook.jpg would have a thumbnail named notebook_t.jpg.

This means that I would have to build the new file path from scratch:

path + original filename + "_t" + original file extension

Enter fullscreen mode Exit fullscreen mode

So how do you do this in Hugo’s templating language?

  1. You build strings via printf.

    Example: {{ printf "%s%s" "foo" "bar" }}foobar

  2. There are multiple path.xyz methods which expect the complete path to a file and return parts of it (what I need: directory, filename, extension).

    Example: {{ path.BaseName .RelPermalink }} ⇒ for notebook.jpg as the current image in a loop, like in the example above, this returns notebook

Syntax: Similar to a lot of other programming languages, nested function calls in Hugo’s template language must be in parentheses.

I.e. if I want to use the printf example from above, but instead of "foo" I want to pass the path.BaseName example (also from above), the correct syntax is:

{{ printf "%s%s" (path.BaseName .RelPermalink) "bar" }}

Enter fullscreen mode Exit fullscreen mode

So this is the line of the shortcode that creates the thumbnails, which must be replaced:

{{ $resized := .Fill "150x115 q20" }}

Enter fullscreen mode Exit fullscreen mode

And the new version which creates path + original filename + "_t" + original file extension filenames as intended:

{{ $thumbname := printf "%s/%s%s%s" (path.Dir .RelPermalink) (path.BaseName .RelPermalink) "_t" (path.Ext .RelPermalink) }}
{{ $resized := .Fill "150x115 q20" | resources.Copy $thumbname }}

Enter fullscreen mode Exit fullscreen mode

The commit with this change is here.


3. Conclusion

Here is the final shortcode one last time - with EXIF image captions, logo overlays and pretty filenames:

{{ $logo := resources.Get "img/overlay-logo.png" }}
{{ $image := (.Page.Resources.ByType "image") }}
{{ with $image }}
    {{ range . }}
    {{ $thumbname := printf "%s/%s%s%s" (path.Dir .RelPermalink) (path.BaseName .RelPermalink) "_t" (path.Ext .RelPermalink) }}
    {{ $resized := .Fill "150x115 q20" | resources.Copy $thumbname }}
    {{ $x := sub .Width (add $logo.Width 10) }}
    {{ $y := sub .Height (add $logo.Height 10) }}
    {{ $withlogo := .Filter (images.Overlay $logo $x $y) | resources.Copy .RelPermalink }}
    <a href="{{ $withlogo.Permalink }}" data-lightbox="x" data-title="{{ with .Exif }}{{ .Tags.ImageDescription }}{{ end }}"><img src="{{ $resized.Permalink }}" /></a>
    {{ end }}
{{ end }}

Enter fullscreen mode Exit fullscreen mode

For the same demo image as above (notebook.jpg), the HTML produced by this shortcode looks like this:

<a href="http://localhost:1313/galleries/gallery1/img/notebook.jpg" data-lightbox="x" data-title="">
    <img src="http://localhost:1313/galleries/gallery1/img/notebook_t.jpg" />
</a>

Enter fullscreen mode Exit fullscreen mode

Top comments (0)