Adding category and tag archive pages to Jekyll

Getting it done without plugins.

Posted by Mike Apted on Tuesday, December 15, 2015

The next incremental upgrade I wanted to make to this site was the ability to incorporate category and tag based post archive lists and navigation from the right sidebar.

There are some plugins available if you Google around, but I wanted to try and implement something simple and using only the stock Jekyll install. To accomplish this I did the following:

Categories

Create a category layout file “_layouts/category.html” which extends my regular page layout:

---
layout: page
---
<h2>Posts related to: {{ page.title }}</h2>

{% unless page.content == '' %}
    <p>{{ page.content }}</p>
{% endunless %}

{% unless site.categories.[page.category] | size > 0 %}
    <p>No posts in this category at this time.</p>
{% endunless %}

{% for post in site.categories.[page.category] %}
<div class="post-preview">
    <a href="{{ post.url | prepend: site.baseurl }}">
        <h2 class="post-title">            
            {{ post.title }}
        </h2>
        {% if post.subtitle %}
        <h3 class="post-subtitle">
            {{ post.subtitle }}
        </h3>
        {% endif %}
    </a>
    <p class="post-meta">
        Posted by 
        {% if post.author %}
        {{ post.author }}
        {% else %}
        {{ site.title }}
        {% endif %} 
        on {{ post.date | date: "%B %-d, %Y" }}
    </p>
</div>
<hr>
{% endfor %}

Create a directory in the root of your site called “category”. In that directory place a file for each category you wish to use in the following format, where the name is the category slug. For example, the file “category/aws.html” would contain:

---
layout: category
title: AWS
category: aws
---

For each page you create an HTML page for in the “category” directory you will get an archive of all those posts using the layout from “_layouts/category.html”. Tags

I followed the same process for the categories with the following differences:

  • Change “page.title” to “page.tag” in “_layouts/tag.html”
  • Change “page.category” to “page.tag” in “_layouts/tag.html”
  • Create a “tags” directory and place tag files in that directory
  • Change “category: xxx” line to “tag: xxx” in “tags/xxx.html” files

Categories are shown on all non-post pages in the right sidebar with the following code in “_layouts/page.html”:

<h3>Categories</h3>
{% for category in site.categories %}
    <a href="/category/{{ category[0] }}/" style="text-decoration: none;">{% if category[0] == 'aws' %}{{ category[0] | upcase }}{% else %}{{ category[0] | capitalize }}{% endif %}</a><br />
{% endfor %}
<p />

Tags are shown in a similar fashion in “_layouts/page.html” and then in “_layouts/post.html” we show that page’s tags in the right sidebar with the following:

<h4>Tags</h4>

{% for tag in page.tags %}
    <a href="/tags/{{ tag }}/">{{ tag }}</a>
{% endfor %}

Final Thoughts

This approach has the obvious downside of needing to manually add each category and tag to the site structure as you use them for the first time, however, for a simple site like this it seems a reasonable trade off to adding complexity with additional 3rd party plugins.