Hello, Image Galleries

I’ve been sorting through a whole lot of photos that I’d like to get online in the near future. Some have been posted on various social media sites, or photo hosting sites, or my own old photo galleries on previous iterations of this site. It’s time to get the good ones back up on the newest incarnation of frotz.net.

The nice thing about Hugo is that you can setup “shortcodes” to generate bits of pages. This keeps the markdown “source” simple and means you can make things fancier over time.

I had already make an image shortcode to let me drop in clickable images with some optional alt-text, like:

{{< image stuff.jpg "cool stuff" >}}

simply by adding layouts/shortcodes/image.html:

{{ $src := .Get 0 }}
{{ $alt := .Get 1 }}
<a href="{{ $src }}"><img src="{{ $src }}" alt="{{ $alt }}"></a>

For galleries I wanted something a little fancier, invoked like so:

{{< gallery >}}
{{< photo PXL_20210924_183634610.jpg >}}
{{< photo PXL_20210924_184206856.jpg >}}
{{< photo PXL_20210924_184257468.jpg >}}
{{< photo PXL_20211026_033035269.jpg >}}
{{< photo PXL_20211026_070237032.jpg >}}
{{< /gallery >}}

This Image Gallery addon was a good start. It had some simple CSS for arranging a list of thumbnails and Hugo templating, but it wanted to just scoop the images out of the filesystem. I wanted to be able to manually control presentation order and (once I wire it up) write captions, descriptions, etc inline.

I ended up with layouts/shortcodes/gallery.html:

.pixgrp {overflow: auto; margin-left: -1%!important;}
.pixgrp li {float: left; display: block; margin: 0 0 1% 1%; width: 32%;}
.pixgrp li a {text-align: center; text-decoration: none!important; color: #777;}
.pixgrp li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.pixgrp li a img {width: 100%; display: block;}

<ul class="pixgrp">{{ .Inner }}</ul>

document.addEventListener('DOMContentLoaded', (event) => {
    new SimpleLightbox({elements: '.pixgrp a'});

and layouts/shortcodes/photo.html:

{{ $alt := .Get 1 }}
{{ $src := .Page.Resources.Get (.Get 0) }}
{{ $img := $src.Resize "300x" }}
{{ $big := $src.Fit "1600x1600 q90" }}
<li><a href="{{ $big.RelPermalink}}"><img src="{{ $img.RelPermalink }}" alt="{{ $alt }}"></a></li>

Which use the specified images as source imagery and resize them to 300px thumbnails and 1600px large images.

I also wired up Simple Lightbox for a fancier click-to-embiggen gallery experience (thus the little chunk of javascript).

Tossing simpleLightbox.js and simpleLightbox.css into assets/js and assets/css, respectively and adding references to hugo.toml (as below) took care of the rest:

  css: [ "css/simpleLightbox.css" ]
  js: [ "js/simpleLightbox.js" ]

I like storing the original images in the content directory next to the index.md, but by default Hugo publishes all included assets, so adding this to the page’s metadata is needed to avoid that:

  publishResources: false

My test case was some photos from 2021 when I upgraded my home office with fancy, new, more robust desks. I expect to put a lot more (and possibly more interesting) photos online soon.