Index, Projects, About, Links

Tags in Jekyll

Here is a solution how to generate pages for each tag that will list all posts for a tag. To assign tags to a post, just put their names, space separated (or as a YAML array if you prefer this way), in the front matter:

layout: post
title: Tags in Jekyll
description: Adding tags to a Jekyll powered website
summary: Adding tags to a Jekyll powered website.
comments: true
tags: [tags, jekyll]
published: true

That sets up the post to have tags. To get the tags pulled onto a page, create two files: _layouts/tag.html and _plugins/tags.rb. The _layouts/tag.html file is necessary for the _plugins/tags.rb script to actually run. Put the following plugin at _plugins/tags.rb:

module Jekyll
  class TagPageGenerator < Generator
    safe true

    def generate(site)
      tags = { |post|['tags'] || [] }.to_set
      tags.each do |tag|
        site.pages <<, site.source, tag)

  class TagPage < Page
    def initialize(site, base, tag)
      @site = site
      @base = base
      @dir  = File.join('tag', tag)
      @name = 'index.html'

      self.read_yaml(File.join(base, '_layouts'), 'tag.html')['tag'] = tag['title'] = "Tag: #{tag}"

This script creates a directory (folder) for each tag in your blog, and creates an index.html file in it and in that index.html file tag template.

In the _layouts/tag.html file, put this:

layout: default

  {% for post in site.posts %}
  {% if post.tags contains page.tag %}
  <li><a class="post" href="{{ post.url }}">{{ post.title }}</a></li>
  {% endif %}
  {% endfor %}

At the end of each post add the following:

  {% for tag in page.tags %}
  <a class="post" href="/tag/{{tag}}">#{{tag}}</a>{% unless forloop.last %}, {% endunless %}
  {% endfor %}

That’s it!