Debugging shortcodes

Hi,
I’m trying to understand how shortcodes work by creating my own before moving on to using complicated ones. I have this shortcode in
layouts/shortcodes/img.html:

{{ $class := or (.Get "class") "center" }}

{{ printf "test_print"}}

{{ $image = resources.GetMatch (.Get "src") }}

{{ $caption := "" }}

<img src="{{ $image }}" alt="{{ $caption }}">

where I’m trying to print a test string and add added a supplied image with some alt text. I call it as such:
{{% img src="/images/f1/track.jpg" %}}

but when I run hugo I get the error:

failed to render shortcode “img”: failed to process shortcode: “C:\Users\manas\Desktop\website-backend\framework\layouts\shortcodes\img.html:3:37”: execute of template failed at <“src”>: undefined variable: $image

I’m not sure why it can’t find the image. I do have an image at static/images/f1/track.jpg in my project. If I use vanilla markdown image reference, it works i.e., ![test_img](/images/f1/track.jpg).
What am I missing? Also, am I using the print statement correctly? Is it printed in the generated HTML? Or to the console?

As the error message said, there is no $image variable, You should declare and assign a value to $image.

{{ $image := resources.GetMatch (.Get "src") }}

Ah that was stupid of me, did not notice the colon. Here is my new shortcode:

{{ $class :=  or (.Get "class") "center" }}
{{ $image := resources.GetMatch (.Get "src") }}
{{ $caption := "" }}
{{ printf (.Get "src")}}
<img src="{{ $image }}" alt="test test test ">

with invocation {{% img src="/images/f1/track.jpg" %}}
this only prints /images/f1/track.jpg in the generated HTML. There is no img tag in the HTML.
What am I missing?
I apologize if this is a stupid question (it probably is) but I’m really not sure what is going on.

I guess the raw HTML was omitted, you can enable it by following configuration, see Configure markup | Hugo.

markup:
  goldmark:
    renderer:
      unsafe: true

Yay progress!

I add this to my config file:

[markup.goldmark.renderer]
unsafe = true

Still no picture, but I at least get the img tag in the HTML output:
image

Why did Hugo put the src value in a <p> tag, and not src as written in the shortcode?

Edit: Ah the <p> was created because of the print statement.

Not sure, does the following code work?

<img src="{{ $image.RelPermalink }}" alt="test test test ">

That gives this error:
failed to render shortcode "img": failed to process shortcode: "C:\Users\manas\Desktop\website-backend\framework\layouts\shortcodes\img.html:4:19": execute of template failed at <$image.RelPermalink>: nil pointer evaluating resource.Resource.RelPermalink

Edit: googling this error says that I need to mark my image as an asset. I’ll try that.

But I still don’t understand why the original <img src="{{ $image }}" alt="test test test "> does not work.

Perhaps some images doesn’t exist, you could check, and output the warning message to console (terminal).

{{ with $image }}
  <img src="{{ .RelPermalink }}" alt="test test test ">
{{ else }}
  {{ warnf "image not found: %s" (.Get "src") }}
{{ end }}

Yay more progress!
The warn code does print out the warning:

But why does it find the image when I write ![test_img](/images/f1/track.jpg) and not find it when I use the shortcode? Is the default search path for shortcodes different?

resources.GetMatch find resources from the assets folder. Is the /images/f1/track.jpg located in a folder other than assets? Such as static.

Ah I see! Yes that was the issue - I had to move the image to the assets folder.

Thank you for the help, razon.

1 Like

Is this supposed to set the class to class=“something” from the markdown shortcode and if not set it to center? I didn’t know “or” could work there. Interesting.
I have been doing it like this:
{{- $alt := .Get “alt” | default page.Title }}

Honestly, I have no idea. I found it on some blog post which as you mentioned is 6 years old. Perhaps this was the old syntax.

@andrewd72 @manas96

That syntax is valid, but wasn’t mentioned/documented on Hugo docs.

or
Returns the boolean OR of its arguments by returning the
first non-empty argument or the last argument, that is,
“or x y” behaves as “if x then x else y”. - Golang text template functions.

1 Like

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