Hugo, Shortcodes, & XKCD refs
xkcd style popup references in Hugo
Way back when I started with hugo, a few days ago, I said in this post that I really liked the xkcd footnote/reference popup/popover things[1] he uses in his “what if?” posts.
I decided to try to add them to Hugo, first just as part of a theme, then make it easier to use them by making a shortcode for them. After many travails* with a pure css approach, I realized that jQuery was already loaded in the theme I was using anyway, and that using the same approach they used would be simple and easy, and work on mobile as well as desktop (one of the issues I had with some pure CSS approaches)
After getting the span based html/css/js version working I went on to making a shortcode version so I could do something like this:
{{% refpo "[1]" "Like this!" %}}
vs. this
<span class="ref"><span class="refnum">[1]</span><span class="refbody">Like this!</span></span>
If the popup should have a larger chunk of text, links, etc. arbitrary markdown or html, I could do this:
{{% refpo "[2]" %}}Lots of stuff, with [links](http://www.xkcd.com) and some html <i>italic tags</i> etc.{{% /refpo %}}
Which would give me this[2] .
That is useful because Markdown isn’t rendered in the 2nd arg in the single shortcode version, though html is. For example same as above in single version[3] .
Unfortunately, I ran into an issue where the non-paired version of the shortcode causes extra <p>
tags to be placed around some of the shortcodes.[4]
. Apparently this is an ongoing and hard to eradicate set of issues, but also I’m new to hugo, go, and shortcodes so it’s certainly possible it’s definitely the case I’ve misunderstood something.
The shortcode is pretty simple and I’ve tried a few variations and not been able to avoid the extra <p>
tags in any variant where I tried to accomplish both variations in one shortcode. For example,
<span class="ref"><span class="refnum">{{.Get 0}}</span><span class="refbody">{{ if len .Params | eq 2 }}{{.Get 1|safeHTML}}{{end}}{{ with .Inner}}{{ .|safeHTML}}{{end}}</span></span>
causes the issue. It seems that having .Inner
is part of the trigger for the issue. I thought maybe I couldn’t test the existence of .Inner
like that, so I tried this variant:
<span class="ref"><span class="refnum">{{.Get 0}}</span><span class="refbody">{{ if len .Params | eq 2 }}{{.Get 1|safeHTML}}{{end}}{{ if len .Inner}}{{ .Inner|safeHTML}}{{end}}</span></span>
But the actual issue turned out to be that the existence of .Inner
in the shortcode itself (whether or not it has a value) is a flag of sorts to hugo which makes it consider the shortcode to be the paired type, as per discussion here. Apparently if you don’t then use closing tags, bad things happen ranging from the extra <p>
codes to chunks of your text getting pulled into the shortcode. Once I knew that, I thought everything would be ok because I’d read
A shortcode with.Inner
content can be used without the inline content, and without the closing shortcode, by using the self-closing syntax:
{{< innershortcode />}}
That quote uses the “shortcode without markdown syntax” rather than the “with markdown syntax”, but I figured it was the same for both. Either I was wrong about it working for the with markdown version, or something is wrong altogether, because when I do
{{% refpo "test1" "Some stuff" /%}}
I get a hugo error from the next shortcode about not having a closing shortcode* . But if I do:
{{% refpo "test1" "Some stuff" %}}{{% /refpo %}}
Things work fine.
So, based on that, kinda makes the shortcode not so short for the simple case. So I broke down and made two different shortcodes*
, poref
for the simple, non-paired case, and porefx
for the extended, paired version that can handle markdown, etc.
poref:
<span class="ref"><span class="refnum">{{.Get 0}}</span><span class="refbody">{{ if len .Params | eq 2 }}{{.Get 1|safeHTML}}{{end}}</span></span>
porefx:
<span class="ref"><span class="refnum">{{.Get 0}}</span><span class="refbody">{{ .Inner|safeHTML}}</span></span>
I’d considered using a scratch variable and making the refnum arg optional, with it counting up on its own if not provided, but I kind of like having arbitrary reference indicators, whether it’s 1, [1], *, or whatever. So I think I’ll call them done for now and move on.
I mean, it’s not groundbreaking or anything, but I think it’ll be handy. I’d prefer a shorter syntax more akin to markdown footnotes, but it’s not awful.
Now to work on the style a bit and figure out if I should use a different main font for the whole site - seeing too many jaggies for my taste here. I didn’t really notice it on the original HTML5 UP theme, so need to investigate.
Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Email