Streamlining With Shortcodes

One of the most powerful features of Hugo is shortcodes. Shortcodes allow users to programmatically generate HTML. One of the most tedious parts about posting my monthly dividend income update is copying/pasting the company names. In the past, I ordered the list alphabetically by stock ticker, but I also put the ETFs at the end. Because I’m human, sometimes I make mistakes and the list is not correctly sorted. Now with shortcodes, I can do it consistently. If I decide that I want to order the list alphabetically by company name, as I have done so on this website, it’s easy to apply that change to all previous posts as long as those previous posts use the same shortcode. Let’s dive into how I did this.

There is a data directory in Hugo that allows you to use configuration to generate content for the website. This is perfect because I only need this file to generate static content. You can read more about Hugo’s directory structure if you want. In the data directory, I store a JSON file called stocks.json that maps a stock ticker to a company name. The JSON file looks like this:

1{
2  "AAPL": "Apple Inc",
3  "ABBV": "AbbVie Inc",
4  "BEPC.TO": "Brookfield Renewable Corp",
5  "BIPC.TO": "Brookfield Infrastructure Corp",
6  "BLK": "Blackrock Inc",
7  ...
8}

I wrote a shortcode, named stocklist.html, that takes in a comma-separated list of stock tickers and produces an HTML list that’s sorted by company name. The list of stock tickers does not have to be in any particular order. The ordering is performed by the shortcode. The shortcode looks like this:

 1{{- $tickers := split (replace (.Get "tickers") " " "") "," }}
 2{{- $list := slice }}
 3{{- range $tickers }}
 4  {{- $name := index $.Site.Data.stocks . }}
 5  {{- if (eq $name nil) }}
 6    {{- $list = $list | append . }}
 7  {{- else }}
 8    {{- $list = $list | append (printf "%s (%s)" $name .) }}
 9  {{- end }}
10{{- end }}
11<ul>
12{{- range sort $list }}
13<li>{{ . }}</li>
14{{- end }}
15</ul>

If there is no company name in the JSON file, it will print the stock ticker, which will indicate that JSON configuration is missing.

Finally, I include the shortcode in my post:

1{{< stocklist tickers="BIPC.TO, VTI, AAPL" >}}

Which produces a list like this:

  • Apple Inc (AAPL)
  • Brookfield Infrastructure Corp (BIPC.TO)
  • Vanguard Total Stock Market ETF (VTI)

Now it takes less time to write a dividend income update post.