How to implement proper blog tagging with Jekyll

Goals

I can't imagine blog without tagging. Unfortunatelly, out-of-the box tagging support in Jekyll is very limited. But Jekyll is very extensible which makes it possible to implement tagging.

My goals for the tagging in blog:

  • To be able to tag any post with any amount of tags which I can invent on-the-fly
  • To have a list of all tagged posts grouped by tags
  • To print a list of tags under each tagged post. Every tag shall lead to a page with a list of posts with the same tag (see this page as an example). The tags shall be displayed in the brief version of the post (in the blog index page) and under the post page.

Goal 1: tagging of the posts

It is really simple. Just add variable tags to every post (in the YAML frontmatter) you would like to tag:

tags: [tag1,tag2,tagN]

Goal 2: List of all tagged posts

This is also pretty simple. The following template will generate list of tags:

<h2>{{page.title}}</h2>

{% capture tags %}
  {% for tag in site.tags %}
    {{ tag[0] }}
  {% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}

{% for tag in sortedtags %}
  <h3 id="{{ tag | escape }}">{{ tag }}</h3>
  <ul>
  {% for post in site.tags[tag] %}
    <li><a href="{{site.baseurl}}{{ post.url }}">{{ post.title }}</a></li>
  {% endfor %}
  </ul>
{% endfor %}

(Idea is adapted from stackoverflow answer. Thanks, Christian!)

Generated page can now be added to your site.

Goal 3: print list of hyperlinked tags under post

This is the most complicated part.

First step is to follow the guide Tags in Jekyll. At the end you will have a page with tagged articles for every tag. I modified a little tag_index.html from Charlie's example.

Now we need to print proper hyperlinks at the end of the post.

Add file tagsforpost.html to your _include folder:

{% comment %}
<!-- Getting and sorting tags alphabetically -->
{% endcomment %}

{% capture mytags %}
  {% for tag in include.tags %}
    {{ tag }}
  {% endfor %}
{% endcapture %}
{% assign sortedtags = mytags | split:' ' | sort %}

{% comment %}
<!-- Tags output: Name + link to the page with list of all the posts with the same tag -->
{% endcomment %}

{% for tag in sortedtags %}
<a href="{{ site.baseurl }}/tag/{{tag}}">#{{tag}}</a>
{% endfor %}

At first stage, tag names are sorted. At the second stage they are printed as hyperlinks.

This file is used by two other templates.

First, post template:

{% include tagsforpost.html tags=page.tags %}

Second, homepage template:

{% include tagsforpost.html tags=post.tags %}

That's it. Congratulations! We are having working setup with tags.

If you liked this post, you can share it with your followers or follow me on Twitter!

#blogging #jekyll #metadata