www.eamoncaddigan.net

Content and configuration for https://www.eamoncaddigan.net
git clone https://git.eamoncaddigan.net/www.eamoncaddigan.net.git
Log | Files | Refs | Submodules | README

index.md (5198B)


      1 ---
      2 title: "Create an expiring Now Page in Hugo"
      3 date: 2024-05-23T20:35:40-07:00
      4 draft: false
      5 categories:
      6 - Meta
      7 - Personal
      8 tags:
      9 - Hugo
     10 ---
     11 
     12 I have added a [now page](https://nownownow.com/about) to my site and a link
     13 to it in the navigation footer below. This isn’t particularly
     14 noteworthy---I’m pretty boring, so its content will probably only interest
     15 a few of my friends and family members (..._maybe_). However, because I have
     16 enough self-awareness to realize that I will “occasionally” let this become
     17 out of date, I devised a workaround that feels worth sharing: I learned how
     18 to make [Hugo](https://gohugo.io) (the program I use to build this site)
     19 hide my now page whenever it gets too old.
     20 
     21 The changes I made to my site configuration are captured in [this Git
     22 commit](https://git.eamoncaddigan.net/www.eamoncaddigan.net/commit/1cf71f032c794808d5a4d6bc5fcd7dd8024074dd.html#h3-0-8).
     23 Since configurations and templates can vary so much between Hugo projects,
     24 I’ll explain each one a little bit in case anyone wants to do something
     25 similar for their site.
     26 
     27 ## Set an expiration time parameter
     28 
     29 First, decide how old you’ll let your page get before it expires, and
     30 convert that value to seconds. For expiration times in days or weeks this is
     31 pretty straightforward: every day has exactly 86,400 seconds, so every week
     32 has 604,800 seconds. For expiration times in months and years, this is
     33 trickier. I recommend approximating months with fractional years; e.g.,
     34 three months is about 1/4 of a year. If you go this route, you’ll need to
     35 choose the duration of a year, bearing in mind:
     36 
     37 - The modal year has 365 days
     38 - The mean year according to our Gregorian calendar has 365.2425 days
     39 - The mean year between 2024 and 2099 (inclusive) has 365.25 days
     40 
     41 Create a new variable in your [Hugo
     42 configuration](https://gohugo.io/getting-started/configuration/) with this
     43 value; I called mine `now_timeout` and set it to ~1/2 a year.
     44 
     45 ```
     46 now_timeout: 15778800
     47 ```
     48 
     49 ## Create your now page
     50 
     51 Create new content to represent your now page:
     52 
     53 ```
     54 hugo new content content/now/index.md
     55 ```
     56 
     57 (Note that all the shell commands should be run from the root folder of your
     58 project directory.)
     59 
     60 Write your post, and make sure the following parameters are included in your
     61 [front matter](https://gohugo.io/content-management/front-matter/):
     62 
     63 ```
     64 ---
     65 title: "Now"
     66 date: [Place the date here]
     67 layout: now
     68 alternate: This page is out of date.
     69 ---
     70 ```
     71 
     72 The `layout` is explained in the next step, and the `alternate` parameter
     73 defines the text that will be shown in place of your now page when it
     74 becomes a “then page”.
     75 
     76 ## Create a ‘now’ layout
     77 
     78 Your now page will probably use a layout similar to your ‘page’ layout. If
     79 you’re still using your theme’s default layout, make a copy and modify it
     80 (replacing `your-theme` with the name of the theme you’re using):
     81 
     82 ```
     83 mkdir -p layouts/page
     84 cp themes/your-theme/layouts/_default/single.html layouts/page/now.html
     85 ```
     86 
     87 Edit this file, replacing the occurrence of `{{ .Content }}` with the
     88 following:
     89 
     90 ```
     91 {{ if ge .Lastmod.Unix (sub time.Now.Unix .Site.Params.now_timeout) }}
     92 {{ .Content }}
     93 {{ else }}
     94 <p>{{ .Param "alternate" }}</p>
     95 {{ end }}
     96 ```
     97 
     98 This is a basic if-then-else construct. If the page hasn’t expired yet, it
     99 will display it as normal, but if it has, the `alternate` text from the
    100 front matter will replace it. The reason that we chose an expiration time in
    101 seconds is that we’re comparing the “Unix time” representations of the page
    102 build time and the now page’s last modification time. If the template
    103 language supported duration values in months, I’d probably use that, but
    104 since it doesn’t it’s not worth the effort.
    105 
    106 ## Add a disappearing “Now” link to your navigation
    107 
    108 This step will be highly theme-dependent. Your site’s navigation is probably
    109 implemented with a [“partial”](https://gohugo.io/templates/partials/); for
    110 example, [my theme](https://github.com/cjtheham/hugo-theme-readable) keeps
    111 this in `themes/readable/layouts/partials/footer.html`. Replacing
    112 `your-theme` with your actual theme name again, and `nav-partial` with the
    113 file that contains the navigation elements, make a copy of the file and edit
    114 it:
    115 
    116 ```
    117 mkdir -p layouts/partials
    118 cp themes/your-theme/layouts/partials/nav-partial.html layouts/partials/
    119 ```
    120 
    121 Now the version of the navigation partial that lives in your
    122 `layouts/partials` directory will override your theme’s. Find the list of
    123 navigation links in your copy, and add a block like the following:
    124 
    125 ```
    126 {{ $now := .GetPage "/now/" }}
    127 {{ if ge $now.Lastmod.Unix (sub time.Now.Unix .Site.Params.now_timeout) }}
    128 <a href="{{ $now.RelPermalink }}">{{ $now.Title }}</a>
    129 {{ end }}
    130 ```
    131 
    132 The `<a>` tag will probably need to be wrapped in a `<p>` or `<li>` tag,
    133 depending on your theme.
    134 
    135 This is similar to the change we made for the now layout, only there’s no
    136 “else” clause, and we’re finding the now page content, storing it in
    137 a variable, and accessing its attributes. This was the part of Hugo theming
    138 that really required me to stop and build a better mental model of the site
    139 generation process.
    140 
    141 ## That’s it
    142 
    143 I hope this is useful to someone else!