Lightbox Gallery with Go Templates in Hugo

I typically spend my weekends shooting landscape photography or hacking away my newest side project. Trying to start the new year off by killing two birds with one stone, I embarked to build a lightweight lightbox component into my fresh hugo blog.

I want a reusable component, that once complete will allow me to quickly drop it into a future blog post in order to share a new series of photos. Given that I chose Hugo based on the ease of writing content in Markdown, I didn't want to deviate from that paradigm. Not wanting to add complex markup with my markdown content files, I quickly landed on implementing new Shortcodes.

Shortcodes within Hugo were designed for adding markup rich content within markdown without breaking its simplicity. Hugo ships with several simple, common Shortcodes including a Shortcode for highlights, Twitter, Vimeo, and YouTube embeds. Below is an example of the included YouTube shortcode.

1    {{< youtube _X8NzH12INY >}}

Hugo will match the Shortcode using the first word in within the snippet to match with a corresponding template. All Shortcode templates must be located within layouts/shortcodes. Parameters can follow the name, are space delimited, and can be either name or positioned. So the following {{< foo bar baz >}} will load the template templates/shortcodes/foo.html and pass bar and baz as parameters to the template.

To start, I'll add a new template to match the gallery markup I want rendered to the page. I need the number of images added to a gallery to be variable, so I'll create a separate Shortcode for the gallery item. I plan on nesting the gallery items shortcode within the gallery. To access this child shortcode I'll use the provided .Inner variable within the gallery template I create.

2<div class="gallery">
3  {{.Inner}}

Next I'll add the template for the gallery items.

 2{{- $src := .Get "src" -}}
 3{{- $alt := .Get "alt" -}}
 4{{- $caption := .Get "caption" -}}
 5{{- $dimension := .Get "dimension" -}}
 6{{ with $dimension }}
 7{{ else }}
 8    {{ $dimension = "1x1" }}
 9{{ end }}
11<div class="gallery-item item-{{$dimension}}">
12    <img class="thumb placeholder" src="{{$src}}" data-src="{{$src}}" data-image="{{$src}}" data-title="{{$alt}}" alt="{{$alt}}">
13    {{ with $caption }}
14        <div class="caption"><span>{{$caption}}</span></div>
15    {{ end }}

Some decisions may start to become clear looking at the above template. I've decided to pass named parameters of "src", "alt", "caption", and "dimension" to the gallery item Shortcode. This will allow me to control variations on the final rendered gallery from the content markdown files. Photo captions will be optional, and dimensions will have a default value of "1x1" if a value is not provided.

Next I'll add the newly created Shortcodes to a content post markdown file.

1{{< gallery >}}
2    {{< gallery-item src="" alt="placeholder 1x1" caption="Caption 1" dimension="1x1" >}}
3    {{< gallery-item src="" alt="placeholder 8x5" caption="Caption 2" dimension="8x5" >}}
4    {{< gallery-item src="" alt="placeholder 3x4" caption="Caption 3" dimension="3x4" >}}
5{{< /gallery >}}

42 ms later, Hugo is done with a fresh site rebuild the newly added shortcode will render the following HTML.

 1<div class="gallery">
 2    <div class="gallery-item item-1x1">
 3        <img alt="placeholder 1x1" class="thumb" data-image="" data-pos="1" data-src="" data-title="placeholder 1x1" loading="lazy" src=""><p class="img_alt">placeholder 1x1</p>
 4        <div class="caption"><span>Caption 1</span></div>
 5    </div>
 6    <div class="gallery-item item-8x5">
 7        <img alt="placeholder 8x5" class="thumb" data-image="" data-pos="2" data-src="" data-title="placeholder 8x5" loading="lazy" src=""><p class="img_alt">placeholder 8x5</p>
 8        <div class="caption"><span>Caption 2</span></div>
 9    </div>
10    <div class="gallery-item item-3x4">
11        <img alt="placeholder 3x4" class="thumb" data-image="" data-pos="3" data-src="" data-title="placeholder 3x4" loading="lazy" src=""><p class="img_alt">placeholder 3x4</p>
12        <div class="caption"><span>Caption 3</span></div>
13    </div>

After some quick Sass and JS using Hugo's pipes asset management (both of which are outside the scope of this blog post), I'm left with a shortcode I can quickly drop into future posts to share a new photo collections. For more comprehensive information on Shortcodes read the Hugo documentation. See the following images below for a fully implemented gallery.

comments powered by Disqus