Setting Up Archive Pages with jekyll-archives
I use the pretty
permalink style in Jekyll, so posts have URLs like /notes/2022/06/01/title/
. What happens if we edit the URL, opening /notes/2022/
?
Without any configuration, we’ll get a page not found error. If we have a 404 page, they’ll get redirected to an existing page (in my case, to the /notes/ page). With a little setup, we can generate archives for the year, month, day, category, and tag pages with the jekyll-archives gem.
Installation is the usual, add the line
gem 'jekyll-archives'
to Gemfile
, run bundle
, then add the following to_config.yml
:
plugins:
- jekyll-archives
The configuration depends on our needs. We can select the enabled archives, the layout(s) that should be used, and the permalink style as well. I’ll describe what I use for my site.
Since I use the pretty
permalink style, I’ll need the year
, month
and day
archives. This will make sure that when a visitor opens the /notes/2022/ or the /notes/2022/07/ or even the /notes/2022/07/01/ pages, they’ll see a list of posts published in that year, month, or on that day. I’ll also need the tags
archive, it’ll generate pages for every tag I use: /tags/jekyll, /tags/ruby, and so on. I only use a single category, so I won’t need the categories
archive.
Attentive readers already noticed that something is missing: jekyll-archives will generate pages for each tag, but it won’t generate a page that lists all of the tags (which should be accessible through the /tags URL). Similarly, it’ll generate pages for /notes/2022, /notes/2022/07, but it won’t generate the main archive page, /notes. We can rectify it easily, but first, let’s set up the individual archive pages.
For the above use case, we’ll need to add the following to _config.yml
:
jekyll-archives:
enabled:
- year
- month
- day
- tags
layouts:
year: year-archive
month: month-archive
day: day-archive
tag: tag-archive
permalinks:
year: /notes/:year
month: /notes/:year/:month
day: /notes/:year/:month/:day
tag: /tags/:name
In the layouts
part I set type-specific layouts for every archive, this way it’s easier to set them up the way I want them. For example, the date archives have a title to describe the time period (Notes from 2022, Notes from 2022-07-01, etc.), but I couldn’t do that with a common layout. The layouts simply loop over the page.posts
variable, which contains the posts for the given time period (or tag), here is the day-archive
for example:
<h2>Notes from {{ page.date | date: '%Y-%m-%d' }}</h2>
<ul>
{% for post in page.posts %}
<li class="flex space-x-6 items-baseline">
<span class="text-sm">{{post.date | date: '%Y-%m-%d'}}</span>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
Now, back to the missing pieces: the main archive pages, /notes and /tags. Let’s create the files: /notes/index.html
and /tags/index.html
.
The notes index is two nested loops: once we iterate over the months that have posts, then inside we iterate over the posts of the given month:
{% assign postsByYearMonth = site.categories.notes | group_by_exp:"post", "post.date | date: '%Y-%m'" %}
{% for yearMonth in postsByYearMonth %}
<h3>{{ yearMonth.name }}</h3>
<ul>
{% for post in yearMonth.items %}
<li class="flex space-x-6 items-baseline">
<span class="text-sm">{{ post.date | date: '%Y-%m-%d' }}</span>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
{% endfor %}
The tags index is similar, with the addition of a sorted tag list at the top:
{% assign tags = site.tags | sort %}
<div class="flex flex-row flex-wrap space-x-6">
{% for tag in tags %}
<a href="{{ tag[0] | slugify }}">{{ tag[0] }} ({{ tag[1] | size }})</a>{% unless forloop.last %},{% endunless %}
{% endfor %}
</div>
<hr>
{% for tag in tags %}
<a href="{{ tag | first | slugify }}"><h3>{{ tag | first }}</h3></a>
<ul>
{% for post in tag[1] %}
<li class="flex space-x-6 items-baseline">
<span class="text-sm">{{ post.date | date: '%Y-%m-%d' }}</span>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
{% endfor %}
With these in place, we have every part of the archives covered: the main notes archive (/notes), the yearly, monthly, daily archives (/notes/2022, /notes/2022/07, /notes/2022/07/01), as well as the main tag archive (/tags) and the individual tag archives (/tags/jekyll, /tags/ruby and so on).
Thanks for reading! If you have any comments, additions, or corrections, feel free to reach me via e-mail.