How To Flag Recent Content in Hugo

In the previous post, I showed how Hugo, a static website generator, can be used to build pages from structured data. This time I’m going to show how it can be used to use date information to flag recent site updates.

My homepage template contains the following bit of Hugo code:

{{ partial "add_flag_app.html" $page }}

If you’ve read the first of my posts on Hugo, you’ll recall that the keyword partial tells Hugo to insert a partial-page template into the main layout it’s currently processing. In the above example, that means pulling add_flag_app.html into the main index.html template.

A little earlier in the main template we have the line

{{ range $page := .Site.AllPages }}

This uses Hugo’s range function to iterate through of the site’s pages — referenced via Hugo’s .Site.AllPages property — and reference the current element via a variable, $page. Setting a reference variable this way allows us to subsequently access an individual page’s metadata or, in the case of the earlier line, pass it in as an argument to the partial function. This sets the ‘context’ used when processing the partial template. Usually, you just write . which indicates the page Hugo is currently working on, in this case the homepage. By passing in $page instead, Hugo interprets the partial template’s code in the context of that page, whatever it happens to be.

This means you don’t have to reference any page directly in the partial template code, only the metadata you expect the supplied context to include. Here’s the partial template:

{{ $t := (time .Params.current_date) }}
{{ $d := now.Sub $t }}
{{ if lt $d.Hours 700 }} <span class="change-badge change-badge-new">Recently Updated</span>{{ end }}

In order, this converts a given page’s current_date value using Hugo’s time function. All custom page front matter fields are accessed via the page’s .Params property. This converted date is stored in a variable, $t.

The next line gets the current date (now) and calls its Sub function. Sub’s argument is the value of $t and it returns the difference between the two dates; this is stored in the variable $d.

Each date value (the one generated by time and the one by now) contains a number of properties, one of which is Hours, the number of hours the date represents. We use the lt function (‘less than’) to test whether fewer than 700 hours separate the page’s date value from the current date. With Hugo if statements, you typically write

if {function} {argument 1} {argument 2}

rather than

if {argument 1} {operator} {argument 2}

but the result is the same: a true or false value. If it’s true, Hugo drops the HTML up to the {{ end }} marker into the rendered page.

As you can see, that HTML adds the words “Recently Updated” formatted using the CSS class change-badge change-badge-new: it’s a green lozenge. The finished result is this:


700 hours is just over four weeks; ASCII and MNU were updated within that period, but Fighting Fantasy Game Manager was not.

Of course, Hugo is a static site generator: the site’s HTML pages are created at build time and will not change until you build the site again. This means that, if I make no further changes, those apps will be flagged as recently updated for ever. In practice, my site will be updated frequently, so that’s not going to be a problem. At the next build, the apps’ dates will be re-checked and if they’re now past the 700-hour limit they will no longer be marked as recent.

However, if you don’t expect to update your site often, you may want to rebuild its content regularly in any case, just to update time-sensitive features like these. You can do it using your OS’ own automation facilities.

More on Hugo…