Creating debug reports with Hugo inline shortcodes

· Around 4 minutes

Recently I discovered that Hugo added support for inline shortcodes like 30 versions ago.

According to bep, the reason I had never heard about them was simple:

A shortcode refresher

To give an idea of what this means, here’s a reminder on how you were required to use shortcodes in the past:

<!-- layouts/shortcodes/notice.html -->
<div class="notice">
  <h3>{{ .Get "title" }}</h3>
  {{ .Inner }}
</div>

<!-- content/blog/example-post.md -->
# This is an example post
{{ notice title="This is a notice" }}
This is the content inside of a notice shortcode
{{ /notice }}
Minor caveat with shortcode syntax1

As you can see, the shortcode internals live in your layouts folder, and have access to your page context as well as all of the various Hugo functions. Your post is only able to pass parameters into the shortcode itself.

Now to be clear, there’s absolutely nothing wrong with doing this. In principle, it’s a good idea for your content to not have any awareness of how it’s being rendered. If you were to change the internals of the notice shortcode once, all of the pages it appears in are instantly updated upon the next render.

In saying that, the introduction of inline shortcodes allows us to do some fun things:

<!-- content/blog/example-post.md -->
# This is an example post Check out some of these funny gags I wrote: {{
readfile.inline }}
<ul>
  {{ range $.Site.Data.gags }}
  <li>{{ . }}</li>
  {{ end }}
</ul>
{{ /readfile.inline }}
Minor caveat with shortcode syntax1

Don’t believe me? Here’s that same inline shortcode embedded in this very post:

Check out these fun gag lines I wrote
  • Has anyone seen my keys? I dropped them in here somewhere...
  • My bluetooth is disabled but I only have bluetooth devices. How do I turn it back on?!
  • Is good software a myth? Perhaps we'll never know
  • The IETF announces BNS - Baby Name System
  • If text is sublime already, how can there be a sublime text 2?
  • Why is it called venture capital if you can just apply for it without walking anywhere?
  • What does the Y in YCombinator stand for?
  • The invention of sport was a mistake!
  • Besides Tele, how many other types of vision are there?
  • When are they going to air Who Wants To Be A Crypto Millionaire?
  • What if NASA was the result of a typo in a government memo proposing "Spice exploration"?
  • What does the "work" in network refer to? There's no such thing as a netrelax after all
  • You have 341 new emails.
  • What even is a TPS report?
  • Do you think anyone has ever been killed by a judge's gavel?
  • I haven't used a mailbox in quite a long time!
  • Thanks for reading this far! I guess you enjoyed the content, hmm?
  • I don't have any good fuel fun facts. I don't even drive!
  • Did you know solo camping is a thing? I should try it sometime.
  • Budgeting is hard. You should try to save a little more for that rainy day!
  • I only ever see baths in hotels. What if they end up becoming extinct?!
  • An internet connected sandwich maker wouldn't be so bad, would it?
  • Someone who is good at the economy please help me plan my startup runway
  • :wq!
  • Apparently you're supposed to feel rested after sleep but I haven't read the literature myself

If any of these look familiar, I just used an inline shortcode to read from the same file that powers the footer.

🗞️ Don't believe everything you read online!

The above shortcode did work (and probably still does) but at the time of writing of update, my site no longer uses Hugo.

I’ve recreated the behaviour you would see using MDX but as such, the example above is no longer literally powered by Hugo shortcodes.

That said, Hugo shortcodes are still a cool middleground to have some dynamic content that is pulled in and statically built without going all in on Javascript.

I haven’t used inline shortcodes to their full potential yet but I’d like to use it to add a bit more flavour to posts in future where having a dedicated shortcode would be a bit overkill.

They’ll always have their place of course! Pick the right tool for the job and all that.

Anyway, that brings me to the actual topic at hand: debug reports.

Let Hugo debug itself for you

There are always some unknowns to any site like “Do any links throw a 404?” or “Are there posts without a description?” and to shed some light on the current situation, we can get a bit meta.

It’s easiest if you just check out the debug section of my site for yourself but the short version is that I’ve been using inline shortcodes to write one off custom reports, that effectively answer these questions through introspection. That’s just a fancy way of saying I write Hugo content (reports) that show the status of other Hugo content.

There isn’t anything super complex at the moment but I used it to clean up posts where the folder names didn’t match slugs as an example.

They automatically update every time the site rebuilds so while I could keep a spreadsheet, this is a nice way of keeping that useful information close to where the action happens.

I made a list of various reports that I’ll consider generating going forward and some will be a bit more tricky than others.

In all likelihood, the most interesting ones will just be reading from data sources generated by external scripts running either locally or via a CI pipeline. It’s nicer to see all this information on one place even if I could just read the logs from my terminal or a pipeline run.

Ah, and before I forget, the actual source for the reports is visible on Github so feel free to borrow anything you’d like to use for your own site. They’re pretty naively written but they get the job done.

Hopefully I’ve given you something to consider and if you think of any interesting report types that aren’t on my list, I’d love to hear about them!

Footnotes

  1. The above isn’t actual syntax but near enough. If I were to type it properly, the shortcode would really render, whereas I’m trying to demonstrate the shortcode internals themselves. To find some real shortcode syntax, check out this section of the Hugo docs. 2