Create a Hugo shortcode

Extending markdown with shortcodes in Hugo

Hugo is a fast, powerful and flexible static site generator. It provides a full feature set out of the box, including the ability to customize and extend the basic markdown functionality. Markdown’s delightful simplicity is great, but it comes with downsides: if you want to do anything more than basic formatting, you quickly end up having to write HTML.

This is where shortcodes come in. They allow you to create HTML snippets that you drop into your markdown. Hugo provides a bunch of shortcodes itself, including support for code highlighting, embedding gists and pulling content from social media.

In this tutorial, we’ll create two custom shortcodes. They will provide an inline tooltip. Using the shortcodes, you will be able to highlight a word or phrase so that when a site visitor hovers over it, they see a brief definition.

Demo

Prerequisites

You will need Hugo and git installed on your machine. This tutorial was developed using Hugo v0.46. You will also need your text editor of choice.

Create a new Hugo project

Run the following command to create your new project:

    hugo new site hugo-glossary-demo

We’re going to use the Hugo Classic theme (because who doesn’t love psychedelic wizards?)

Change to the themes directory:

    cd hugo-glossary-demo/themes

Clone the theme:

    git clone https://github.com/goodroot/hugo-classic.git

Copy the content, static/css and config.toml files and folders into the root of your project.

We’re not going to replace the demo content that comes with the theme. We’ll just go ahead and extend it with tooltips.

Create the shortcodes

Create a new directory named shortcodes in the layout directory, and within it create a file named tooltip.html. Add the following:

    <style>
    .definition {
        visibility: hidden;
        width: 120px;
        background-color: #555;
        color: #fff;
        text-align: center;
        border-radius: 6px;
        padding: 5px 0;
        position: absolute;
        z-index: 1;
        bottom: 125%;
        left: 50%;
        margin-left: -60px;
        opacity: 0;
        transition: opacity 0.3s;
    }
    
    .term {
        position: relative;
        display: inline-block;
        border-bottom: 1px dotted black;}
    
    .term:hover .definition {
        visibility: visible;
        opacity: 1;
    }
    </style>
    <span class="term">
     {{ .Inner }} 
    </span>

The majority of that snippet is the CSS. The shortcode itself is very simple: wrap a span with the class “term” around anything we apply the shortcode to.

Let’s create our second shortcode. Make another file, named definition.html, and add the following:

    <span class="definition">{{ .Inner }}</span>

As with the tooltip shortcode, this wraps the contents of the shortcode in a span. We handled all the styling and functionality in tooltip, so no need for anything else here.

Add the shortcodes to the content

We want our shortcode to wrap around a word or phrase, and we want to allow those words to have all the usual markdown formatting, in addition to our custom behavior. So we are going to use a paired shortcode that allows markdown:

    {{% tooltip %}}your word here{{% definition %}}Word definition here{{% /definition %}}{{% /tooltip %}}

Let’s add this to our sample site, so we can see it in practice. Open _index.md in content/post. Amend the first paragraph as follows:

About twenty years ago {{% tooltip %}}Jobs{{% definition %}}Steve Jobs, legendary founder of Apple.{{% /definition %}}{{% /tooltip %}} and Wozniak, the founders of Apple, came up with the very strange idea of selling information processing machines for use in the home.

We’ve added the shortcodes to Jobs’ name, and provided a brief description of him.

In your CLI, run hugo serve. Navigate to http://localhost:1313/ in your browser, and try it out.

Conclusion

Shortcodes have the potential to be hugely powerful. There are already people crafting their own, and sharing - but much more could be done with this tool. See what you can build!