Hugo

Variables in shortcodes

Hi There.

I’m pretty new in Hugo and maybe it’s a simple cuestion but I can’t find solution. How can I pass dict or array variables to my custom shortcode?
I try with this one but it doesn’t work

{{< gallery data="["blue.jpg", "red.jpg"]" >}}

In a short code I want to loop over the images to display them

The " might be cancelling each other out.

What happens when you use:

{{< gallery data="['blue.jpg', 'red.jpg']" >}}

This will probably result in a value that is a string and needs to be parsed into a dict/slice/array.

1 Like

Thanks for the prompt reply and hint.
For now I solved it in that way:

.md
{{< gallery data=“blue.jpg,red.jpg” >}}

shortcodes/gallery.html
{{ $array := split (.Get “data”) “,” }}

{{ range $array }}
    <img src='gallery/'{{ . }}' />
{{ end }}

The next question is: How to send “alt” for each image? Dict like:
{"images": [{"image": "image1.jpg", "alt": "Alternative text for image 1"}, {"image": "image2.jpg", "alt": "Alternative text for image 2"}]}

that would be awesome :slight_smile:

Hi!

Instead of using a shortcode array, you can use Page Resources. So you simply use front matter params for this.


For galleries I use a different approach: I, too, need multiple galleries on a page. All images for each gallery live in a seperate subfolder.

In the shortcode I use something like this:

{{ $dir := .Get "src" | default "gallery" }}
{{ with (.Page.Resources.ByType "image").Match (printf "%s**" $dir) }}

That’s convenient because everything happens almost automatically.

OK @Grob by how you pass alt attribute for image in gallery?

Thanks to @pkollitsch hint, for now I solved it in tjis simple way:

content/any-page.md
{{< gallery data=“blue.jpg|Oridinary Blue image,red.jpg|Nice red image” >}}

layouts/shortcodes/gallery.html
{{ $array := split (.Get "data") "," }}

{{ range $array }}
	{{ $item := split . "|"}}

	{{ $image := index $item 0 }}
	{{ $alt := index $item 1 }}

	<img src="/path-to-gallery/{{$image}}" alt="{{$alt}}">
	
{{ end }}

It work’s fine and it’s enough to solve my problem. In fact you can pass any arrays in that way. The only thing you have to do is to convert each string element to data. Just take care of delimiters :slight_smile:

It really depends on what you want to do. If it’s a gallery I would use nested shortcodes. There is a nice sample in the documentation:

Hi!

This is a more complete example:

{{ with (.Page.Resources.ByType "image").Match (printf "%s**" (.Get "src" | default "gallery" )) }}
  {{ range $image := . }}
    {{ $image = $image.Fill "400x300" }}
    <figure>
      <a href="{{ .RelPermalink }}">
        <img src="{{ $image.RelPermalink }}" alt="&nbsp;">
      </a>
      <figcaption>{{ .Params.caption | markdownify }}</figcaption>
    </figure>
  {{ end }}
{{ end }}

.Params.caption is within the .Page.Resources loop and therefore refers to your resources.

Just add this to the front matter of the index.md file containing the gallery:

---
resources:
  - src: gallery/1.jpg
    params:
      caption: My Caption **using Markdown**
  - src: gallery/3.jpg
    params:
      caption: Another Test

By using ** in printf "%s**" $dir you can use file names or folders:

So {{< gallery src="gallery1" >}}

works for

gallery1-01.jpg
gallery1-02.jpg
…

and for

gallery1/

I tried the exactly same approach you are doing some time ago. It just did not work for me, and I was looking for a ‘Hugo out of the box’ solution. That’s why I am mentioning this approach.

1 Like