This blog, which is now generated with Hugo, uses the permalink structure /:year/:month/:slug
(the slug is a url-safe version of the title). There are also “archive” pages, which list the articles posted in a given
month or year. These pages have a permalink structure that compliments the post permalinks: /:year/:month
and /:year
respectively.
Back when this blog was generated with Jekyll, I used a plugin to generate the archive pages but there is no such mechanism in Hugo. It is possible to use taxonomies to accomplish this, but it involves defining a taxonomy for each year in the Hugo config, creating a corresponding layout and also adding redundant frontmatter to each post.
As an alternative, I created 2 new “sections” (top level subfolders in the content folder): archy
and archm
. archy
contains one file per year and archm
contains one file per month. These files can be generated automatically
(see below).
Config
Define permalinks in the Hugo config file:
config.toml
# prevent hugo from creating folders/indexes for each section
disableKinds = ["section"]
[permalinks]
# :title is used if :slug is not defined in post frontmatter
posts = "/:year/:month/:slug/"
archm = "/:year/:month/"
archy = "/:year/"
Templates
Section Layouts
Create a corresponding layout for each section:
layouts/archy/single.html
|
|
layouts/archm/single.html
|
|
layouts/partials/post/archive.html
|
|
RSS Template
You probably don’t want the archy
and archm
pages to appear in the main RSS feed, so ensure your RSS Template uses a range
with a where
clause that limits it to pages of type posts
:
|
|
Note: It is not recommended to set the rssLimit
Hugo config option because it will count pages of all types. This is why the first 10
clause exists in the above example (which causes the feed to display a maximum of 10 items).
Navigation
When disableKinds = ["section"]
is set in the Hugo config, .NextInSection
and .PrevInSection
cannot be used when creating navigation links.
In effect, this:
|
|
becomes this:
|
|
Archive Links Example
You can generate a list of archive links like so:
|
|
Section Content
The archy
and archm
content files each contain a single line of JSON specifying the corresponding date. For example:
content/archy/2008.md
|
|
content/archm/2008-09.md
|
|
Automation
I use the following script to generate the content files for archy
and archm
after analyzing the articles in the posts
section. Note: I use YAML frontmatter in the post markdown files so this script uses the yaml-front-matter
npm module to parse them. Be sure to use a parser that matches your frontmatter format.
scripts/gen-archives.js
|
|
Real Talk
This method provides an alternative to using taxonomies, but it may not be the best fit for every site.
No associated RSS feed is generated for the archive pages. This doesn’t bother me because, for this blog, a feed of posts in a given time frame does not seem useful. Your requirements may vary.
If sections are disabled with the disableKinds
config option, permalinks must be defined for any section with content that should be output. If you use additional sections (events, etc) there will be no RSS feed automatically generated for those sections. Taxonomy feeds (for tags, etc) will still be generated.
The additional build step of running a script to scan the posts folder and generate the archy
and archm
content is worth it to me to keep the post’s date frontmatter as the canonical source for when it was posted (as opposed to defining a redundant taxonomy in each post). Also, the script only has to output JSON data which is less brittle than attempting to generate layouts and programmatically modifying the Hugo config (which would be required to automate the taxonomy-based method).