In this post I explain about creating a simple custom shortcode in Hugo.
But, before starting off, we need to know what shortcodes are and the way they works. So firstly I’m going to walk us through a little bit explanation of that.
Intro
Shortcodes are one type of templates in Hugo—like partials. The cool thing about this type of template is that it can accept parameters that makes it easy when dealing with generated content or when you want to customize the output of a snippet.
In a nutshell, shortcodes are snippets that you can insert in your site content.
File location
Templates of shortcodes are stored in /layouts/shortcodes/
directory. There
are two kinds of this directory. The first one is the one which resides in your
Hugo site’s root directory. And the other one is under the themes’ root
directory. Shortcodes that are stored in the first kind of directory is
prioritized by Hugo. This way you can override built-in shortcodes provided by
themes.
<YOUR-HUGO-SITE>/layouts/shortcodes/<SHORTCODE>.html
<YOUR-HUGO-SITE>themes/<THEME-NAME>/layouts/shortcodes/<SHORTCODE>.html
Creating a custom shortcode
As the title says, I’ll walk you through the logic and process of creating a
custom shortcode for a use case which is rendering a string parameter inside a
pair of <kbd>
tag.
In this process, we will go backward. We will go from the end result—i.e. defining what we want to achieve—to the beginning i.e. the step-by-step process of the creation.
Alright, here we go. Let’s get started with defining what we want to get from
this shortcode. Starting with name, we will choose kbd
for the name of this
shortcode.
And below is the rendered result that we want this custom shortcode produce:
<kbd>Ctrl</kbd>
Based on the wanted result above, we need one parameter to be passed on to the
shortcode—which is the string Ctrl
.
According to Hugo’s documentation of custom shortcode example, single positional is
the type of parameter that our kbd
shortcode needs—just like the youtube
shortcode example
listed in the documentation.
The following code is how we use the aforementioned youtube
shortcode:
{{< youtube 09jf3ow9jfw >}}
As you can see, the youtube
shortcode needs only one parameter, the
09jf3ow9jfw
string, which is the ID of a YouTube video. The code would load
the template file at /layouts/shortcodes/youtube.html
:
<div class="embed video-player">
<iframe class="youtube-player" type="text/html" width="640" height="385" src="https://www.youtube.com/embed/{{ index .Params 0 }}" allowfullscreen frameborder="0">
</iframe>
</div>
And render it as:
<div class="embed video-player">
<iframe class="youtube-player" type="text/html"
width="640" height="385"
src="https://www.youtube.com/embed/09jf3ow9jfw"
allowfullscreen frameborder="0">
</iframe>
</div>
Now, it’s time to go back to our kbd
shortcode. We will do the same thing as
the youtube
shortcode.
The first thing is we need to create a file, kbd.html, and store it inside
the /layouts/shortcodes/
directory.
Below is the content of the kbd.html file:
<kbd>{{ index .Params 0 }}</kbd>
Do you notice the {{ index .Params 0 }}
? Yup, that’s how we tell Hugo where to
insert the passed parameter. It will insert only the first parameter
passed—specified by the number 0
which is the index of the first parameter.
And, that’s all. Now we can use our kbd
shortcode.
This
{{< kbd Ctrl >}}
will be rendered as:
<kbd>Ctrl</kbd>
Note that parameters with non-alphanumeric characters such as ⌘
need to be
quoted like this "⌘"
or Hugo will throw an error that says something like:
Rebuild failed:
"/home/user/site/content/file.md:21:25": unrecognized character in shortcode action: U+2318 '⌘'. Note: Parameters with non-alphanumeric args must be quoted
For more information about shortcode templates, you refer back to its official documentation here.
Background
I was wondering of what happened when viewing one of my snippets
page whose some characters
that are supposed to be marked up in a pair of <kbd>
tag, but the they
weren’t. So, in order to find out what the problem was, the first thing I needed
to do was inspecting the respective elements. I needed to make sure if the
problem was in the client side before jumping into the server side.
And, my wonder got answered. What I found was that each tag—the opening and
the closing tags—was replaced with an HTML comment
<!-- raw HTML omitted -->
. Obviously, this was a rendering problem on the
client side—because the elements weren’t rendered i.e. marked up properly as
I wanted them to be—and also on the server side because there was a mistake
in the source document that made Hugo not render it as I intended it to.
Apparently, I was using a wrong way to mark-up the document by adding in raw HTML code to it. The solution to this problem would be to find out the correct way of adding raw HTML to Markdown content.
Having stumbled upon a YouTube video explaining about shortcodes, it kind of dawned on me that they are the way to go for working around this issue.
Later, I found out that Hugo already had an explanation regarding this here.
Hugo loves Markdown because of its simple content format, but there are times when Markdown falls short. Often, content authors are forced to add raw HTML (e.g., video
<iframe>
’s) to Markdown content. We think this contradicts the beautiful simplicity of Markdown’s syntax.Hugo created shortcodes to circumvent these limitations.