Dynamic content in static websites in Hugo

Posted by ads' corner on Thursday, 2023-03-02
Posted in [Hugo][Social-Networks]

With people moving away from Twitter, mostly to Mastodon, discovering the new accounts became a problem.

For people in the PostgreSQL community I created a website which lists different social media accounts. This website is part of the “PostgreSQL Person of the Week” interview project, however the data source is dynamic, and stored in a different repository. This allows me to keep the repository for the website private, but publish the data for the social media links - this data is public anyway. The interview repository is private, because who wants to see upcoming interviews anyway? ;-)

The interview website is made with Hugo, a static website generator. Normally Hugo looks for content, templates, and other data in the current directory - my private repository.

As part of compiling the website, Hugo can fetch external data, either in JSON or CSV format. This is using the getJSON() and the getCSV() functions, which can be used in Shortcodes, as example.

How does that work?

Create a Shortcode in Hugo

A Shortcode is a small piece of a template, which optionally can also include Hugo functions. In my case it includes the getJSON() call, and then loops over the JSON and generates the output based on the data.

{{ $friends := getJSON "https://raw.githubusercontent.com/andreasscherbaum/<...>.json" }}
{{ range $friends_name, $friends_data := $friends }}
{{ end }}

The actual Shortcode code is a bit more complex, it differentiates between interviews and also splits up Mastodon and Twitter links and in addition to the link also shows the username. The details are not part of this blog post.

The code for the Shortcode is placed in: layouts/shortcodes/postgresfriends.md.

Refresh the cache

The downloaded data is cached, in $TMPDIR/hugo_cache/projectname/filecache/. The exact location depends on which path $TMPDIR is in your system, usually something like /tmp. One way to trigger a refresh of the outside data is by deleting the cache, another way is by using the --ignoreCache commandline option. However this will trigger a reload every time the website is rebuild, even in preview mode.

A more convenient method, at least for me, is to specify a max age for the cache. This can be defined in config.toml:

    maxAge = "1h"

This will cache the JSON data for one hour, and then trigger a reload. This is ok when I work on a new interview, and will refresh the data when I publish an interview - which usually does not happen at the same time.

Use the Shortcode

Last but not least the Shortcode itself must be used in a static website, in my case the page which builds the /social website.

This website lists Social Media links for #PostgresFriends (in alphabetical order).

{{% postgresfriends %}}


Building static websites in Hugo which include partially dynamic content from external resources is easy to do. It would be more convenient if this works in the website itself, and does not require the loop through building a Shortcode, but this is a minor inconvenience.

Categories: [Hugo] [Social-Networks]