Go big or Go home? The sequel

After a “D’oh!” moment, I refine a bespoke Hugo shortcode.

2021-11-23

The inspiration for this mercifully brief post was a metaphorical, “Why didn’t I think of this before?”-kinda forehead-slap. And perhaps it should have been more than metaphorical.

Back in February, I wrote an article about my conversion of an Eleventy shortcode to a Go-based shortcode for Hugo. Each shortcode’s purpose generated the necessary HTML for responsive handling of an image from my Cloudinary account. While the spaghetti-ish result for Hugo certainly worked, it was ’way more convoluted and hard to read than it needed to be. This post is an attempt to make up for that.

You see, I realized the other day that — “D’oh!” — I’d taken far too literally the process of going from the Eleventy shortcode to its Hugo counterpart. The JavaScript-based Eleventy original was structured to build and then return a string, but that wasn’t necessary for the Hugo shortcode since its result, by default, already was a string. It was as if I had promised you the recipe for a pumpkin pie but, instead, had told you how to type the recipe or, worse, how to spell it out by positioning strands of wet, uh, spaghetti. Maybe in the end you still got a pumpkin pie recipe, but with much more trouble — and at the expense of a ridiculously messy kitchen counter.1

Anyway, let’s get to the real recipe. If you need help with the Hugo-/Go-specific syntax therein, please refer to the original post and its explanatory links.

imgc.html

{{/* init the first set of vars */}}
{{- $respSizes := slice "300" "450" "600" "750" "900" "1050" "1200" "1350" "1500" -}}
{{- $src := .Get "src" -}}
{{- $alt := .Get "alt" -}}
{{- $width := .Get "width" -}}
{{- $height := .Get "height" -}}

{{/*
	I'm separating the Cloudinary-related vars
	for greater flexibility, especially in case
	somebody else wants to borrow this code for
	their own Cloudinary setup and
	transformation ("xFm") choices.
	For example, incorporating the first var
	($cloudName) into the second var ($cloudiBase)
	allows tailoring the shortcode to one's own
	Cloudinary account.
*/}}
{{- $cloudName := "brycewray-com" }}
{{- $cloudiBase := printf "%s%s%s" "https://res.cloudinary.com/" {{ $cloudName }} "/image/upload/" -}}
{{- $LQIPholder := "f_auto,q_1,w_20/" -}}
{{/* $xFmPart1 := "f_auto,q_auto:eco,w_" */}}
{{- $xFmPart2 := ",x_0,z_1/" -}}
{{/*
	Due to the colon in the `q_auto:eco` parameter,
	I type out the value of `$xFmPart1` below to
	avoid the "#ZgotmplZ" annoyance, which I couldn't
	resolve with `safeHTML` or other similar methods.
	See also:
	- https://gohugo.io/functions/safehtml/
	- https://gohugo.io/functions/safehtmlattr/
	- https://stackoverflow.com/questions/36382624/how-to-get-rid-of-zgotmplz-from-html-template-in-golang
	- https://pkg.go.dev/html/template#hdr-A_fuller_picture
*/}}

{{/*
	The following vars seem pointless when we're
	using this for only one type of image, but am
	keeping in case I ever decide to use other
	kinds of images again (e.g., full-sized "hero
	images" with their own specific requirements)
	and, thus, have good reason to select these
	items programmatically.
	Of course, classes vary from site to site,
	but the ones shown here work for my site as of
	this writing.
*/}}
{{- $imgBd5 := md5 $src -}}
{{- $divClass := "relative" -}}
{{- $imgClass := printf "%s%s%s%s%s" "w-full h-auto aspect-" $width "/" $height " lazy" -}}
{{- $nscClass := "containedImage" -}}
{{- $dataSzes := "(min-width: 1024px) 100vw, 50vw" -}}

<div class="{{ $divClass }} bg-center bg-no-repeat bg-cover" style="background-image: url({{ $cloudiBase }}{{ $LQIPholder }}{{ $src }});" aspect-ratio="{{ $width }} / {{ $height }}">
	<img class="{{ $imgClass }}" src="{{ $cloudiBase }}f_auto,q_auto:eco,w_600{{ $xFmPart2 }}{{ $src }}"
	srcset="
	{{- range $i, $respSizes -}}
		{{- if ge $width . -}}
			{{- $cloudiBase -}}f_auto,q_auto:eco,w_{{ . }}{{- $xFmPart2 -}}{{- $src }} {{ . }}w{{ if $i }}, {{ end -}}
		{{- end -}}
	{{- end -}}" alt="{{ $alt }}" width="{{ $width }}" height="{{ $height }}" loading="lazy" sizes="{{ $dataSzes }}" />
	<noscript>
		<img class="{{ $nscClass }}" src="{{ $cloudiBase }}f_auto,q_auto:eco,w_600 {{ $xFmPart2 }}{{ $src }}" alt="{{ $alt }}" />
	</noscript>
</div>

  1. I do concede that this analogy may, amazingly, be even more convoluted than the Hugo shortcode I gave you in the earlier post. ↩︎

NEXT   

PREVIOUS