I have added a now page to my site and a link to it in the navigation footer below. This isn’t particularly noteworthy—I’m pretty boring, so its content will probably only interest a few of my friends and family members (…maybe). However, because I have enough self-awareness to realize that I will “occasionally” let this become out of date, I devised a workaround that feels worth sharing: I learned how to make Hugo (the program I use to build this site) hide my now page whenever it gets too old.
The changes I made to my site configuration are captured in this Git commit. Since configurations and templates can vary so much between Hugo projects, I’ll explain each one a little bit in case anyone wants to do something similar for their site.
Set an expiration time parameter
First, decide how old you’ll let your page get before it expires, and convert that value to seconds. For expiration times in days or weeks this is pretty straightforward: every day has exactly 86,400 seconds, so every week has 604,800 seconds. For expiration times in months and years, this is trickier. I recommend approximating months with fractional years; e.g., three months is about 1/4 of a year. If you go this route, you’ll need to choose the duration of a year, bearing in mind:
- The modal year has 365 days
- The mean year according to our Gregorian calendar has 365.2425 days
- The mean year between 2024 and 2099 (inclusive) has 365.25 days
Create a new variable in your Hugo
configuration with this
value; I called mine now_timeout
and set it to ~1/2 a year.
now_timeout: 15778800
Create your now page
Create new content to represent your now page:
hugo new content content/now/index.md
(Note that all the shell commands should be run from the root folder of your project directory.)
Write your post, and make sure the following parameters are included in your front matter:
---
title: "Now"
date: [Place the date here]
layout: now
alternate: This page is out of date.
---
The layout
is explained in the next step, and the alternate
parameter
defines the text that will be shown in place of your now page when it
becomes a “then page”.
Create a ‘now’ layout
Your now page will probably use a layout similar to your ‘page’ layout. If
you’re still using your theme’s default layout, make a copy and modify it
(replacing your-theme
with the name of the theme you’re using):
mkdir -p layouts/page
cp themes/your-theme/layouts/_default/single.html layouts/page/now.html
Edit this file, replacing the occurrence of {{ .Content }}
with the
following:
{{ if ge .Lastmod.Unix (sub time.Now.Unix .Site.Params.now_timeout) }}
{{ .Content }}
{{ else }}
<p>{{ .Param "alternate" }}</p>
{{ end }}
This is a basic if-then-else construct. If the page hasn’t expired yet, it
will display it as normal, but if it has, the alternate
text from the
front matter will replace it. The reason that we chose an expiration time in
seconds is that we’re comparing the “Unix time” representations of the page
build time and the now page’s last modification time. If the template
language supported duration values in months, I’d probably use that, but
since it doesn’t it’s not worth the effort.
Add a disappearing “Now” link to your navigation
This step will be highly theme-dependent. Your site’s navigation is probably
implemented with a “partial”; for
example, my theme keeps
this in themes/readable/layouts/partials/footer.html
. Replacing
your-theme
with your actual theme name again, and nav-partial
with the
file that contains the navigation elements, make a copy of the file and edit
it:
mkdir -p layouts/partials
cp themes/your-theme/layouts/partials/nav-partial.html layouts/partials/
Now the version of the navigation partial that lives in your
layouts/partials
directory will override your theme’s. Find the list of
navigation links in your copy, and add a block like the following:
{{ $now := .GetPage "/now/" }}
{{ if ge $now.Lastmod.Unix (sub time.Now.Unix .Site.Params.now_timeout) }}
<a href="{{ $now.RelPermalink }}">{{ $now.Title }}</a>
{{ end }}
The <a>
tag will probably need to be wrapped in a <p>
or <li>
tag,
depending on your theme.
This is similar to the change we made for the now layout, only there’s no “else” clause, and we’re finding the now page content, storing it in a variable, and accessing its attributes. This was the part of Hugo theming that really required me to stop and build a better mental model of the site generation process.
That’s it
I hope this is useful to someone else!