Path in img tag onerror renders with \/ path separators instead of forward slash

In a shortcode for images, the final html rendered, in all places except one, writes the path separators / forward slash correctly. The exception is in the <img> tag property of onerror. In that property, is prints the path separators as \/ instead of /. But the way I’m referencing the path is the same for src= as it is for onerror=.

So what is happening? Below is the relevant code from the shortcode (which comes from a theme geeky-hugo), followed by the resulting html:

Shortcode: image.html

{{ $image = .Page.Resources.GetMatch $imagePath }}
{{ $imageExt := path.Ext $image }}
{{ $imageWidth := $image.Width }}
{{ $imageHeight := $image.Height }}
<!-- image processing -->
{{ $options := add (add (string (.Get "w" | default $imageWidth)) "x ") (.Get "o") }}
{{ .Scratch.Set `image` ($image.Resize $options).RelPermalink }}

<!-- fallback image -->
{{ $option := add (string $imageWidth) "x" }}
{{ .Scratch.Set "image_fallback" ($image.Resize $option).RelPermalink }}

<!-- image tag -->
<img 
  loading="lazy" 
  decoding="async" 
  class="{{.Get `c`}} {{.Scratch.Get `image-position`}}" 
  width="{{.Get `w` | default $imageWidth }}" 
  height="{{.Get `h` | default $imageHeight}}" 
  src="{{.Scratch.Get `image`}}" 
  alt="{{.Get `alt`}}" 
  onerror="this.onerror=null;this.src='{{ .Scratch.Get `image_fallback` }}';"/>

As I said, the path for the src= property gets printed correctly but the onerror= property doesn’t. Observe:

Rendered HTML

<img 
  loading="lazy" 
  decoding="async" 
  class="rounded img-center" 
  width="970" 
  height="500" 
  src="/blog/post-1/images/testo_hu4cc21e7a863615a92cd0655f577c12f3_800270_970x0_resize_box_3.png" 
  alt="alter-text" 
  onerror="this.onerror=null;this.src='\/blog\/post-1\/images\/testo_hu4cc21e7a863615a92cd0655f577c12f3_800270_970x0_resize_box_3.png';">

If I do a little debugging and add a {{ print (.Scratch.Get "image_fallback") }} the printed text shows the correct slashes, not the back and forward slashes:

/blog/post-1/images/testo_hu4cc21e7a863615a92cd0655f577c12f3_800270_970x0_resize_box_3.png

Unrelated Extra Credit

  1. What’s the difference between .Scratch variables and custom $image variables?
  2. When using .Scratch variables, this shortcode uses double quotes when Set-ting them and backticks when Get-ing them? Why? What’s the proper way?

First, the string in the onerror attribute is correct. The backslash is an escape character, not a path separator.

Second, there is no need to use a .Scratch anywhere in this shortcode. You’d have to ask the theme author why they didn’t simply use initialize (:=) and assign (=) with custom variables.

Finally, to learn more about backticks vs. double quotes, see:
https://go.dev/ref/spec#String_literals

They said that’s just how they code. What’s the main benefit compared to Scratch? Just cleaner and more typical?

Yikes.

With Hugo v0.47.0 and earlier you had to use a Scratch because you could not assign a new value to a variable after it had been initialized.

The underlying Go limitation was removed over 3 years ago with https://github.com/golang/go/issues/10608.

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