Random element choice in a Hugo HTML template
I run a couple of sites related to my Chinese studies: an East Asian Studies blog, and a Chinese learning resource site.
The content is all free so I have some simple affiliate image links on the
pages to cover the bills. These are just straight forward <a><img></a>
elements with no tracking or anything obnoxious at all. Even then, I don’t want
to have too many adverts on a single page as it would still be a bit much.
A simple way to have fewer advert images but still have different adverts across pages is to select a random choice in the Hugo HTML template when the static site is generated.
After a little bit of fiddling around I got that working like this:
{{ with index ((slice "foobar-1" "foobar-2" "foobar-3") | shuffle) 0 }}
{{ if eq "foobar-1" . }}
<a href="/recommended/foobar-1/"
rel="nofollow"
class="advert">
<img src="/img/foobar-1.png"
class="advert"
alt="Foobar 1" />
</a>
{{ end }}
{{ if eq "foobar-2" . }}
<a href="/recommended/foobar-2/"
rel="nofollow"
class="advert">
<img src="/img/foobar-2.png"
class="advert"
alt="Foobar 2" />
</a>
{{ end }}
{{ if eq "foobar-3" . }}
<a href="/recommended/foobar-3/"
rel="nofollow"
class="advert">
<img src="/img/foobar-3.png"
class="advert"
alt="Foobar 3" />
</a>
{{ end }}
{{ end }}
The {{ with }}
isn’t totally necessary: it could instead be a variable, but
this way seems a bit cleaner in the template. The key part is:
index ((slice "foobar-1" "foobar-2" "foobar-3") | shuffle) 0
That chooses one random element from the given slice each time this template is called. Luckily Hugo / Go templating does call this fresh in each place this template partial is used, so you get different random choices across the site.
This means that each slot gets a single advert link out of a choice of three, keeping the pages cleaner but allowing a range of adverts across the site.
The random choices are fixed for each site generation, but that is fine for my use case. The pages are uploaded to AWS S3 and served via Cloudfront. Mixing up the advert placements each time the site is re-generated seems fine.