How to create a tags and archive page in Jekyll

One feature that I’ve found hard to implement in the Jekyll static website generator is a tags and archive page. After much testing I’ve finally got a solution working as required.

Features and screenshots

List of tags with a count of posts

List of posts in each tag ordered by date newest

In the footer of the post to list the tags and linking to the correct section of the new tags page

Instructions

In your post ensure your are using the tags feature

---
layout: post
published: true
title: Importing CSV files into MySQL from the Linux command line
comments: true
tags: mysql linux
---

Create a folder tags and add a file index.md in it with the following contents

tags/index.md

---
layout: page
title: Tags
---

{% capture site_tags %}{% for tag in site.tags %}{{ tag | first }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
<!-- site_tags: {{ site_tags }} -->
{% assign tag_words = site_tags | split:',' | sort %}
<!-- tag_words: {{ tag_words }} -->

<div id="tags">
  <ul class="tag-box inline">
  {% for tag in tag_words %}
    <li><a href="#{{ tag | slugify }}-ref">{{ tag | replace: '-', ' ' }} <span>{{ site.tags[tag] | size }}</span></a></li>
  {% endfor %}
  </ul>

  {% for item in (0..site.tags.size) %}{% unless forloop.last %}
    {% capture this_word %}{{ tag_words[item] | strip_newlines }}{% endcapture %}
  <h2 id="{{ this_word | slugify }}-ref">{{ this_word | replace: '-', ' ' }}</h2>
  <ul class="posts">
    {% for post in site.tags[this_word] %}{% if post.title != null %}
    <li itemscope>
        <a href="{{ post.url }}">{{ post.title }}</a>
           <span class="entry-date">
              <time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">
                {{ post.date | date: "%B %d, %Y" }}
              </time>
          </span> 
       </li>
    {% endif %}{% endfor %}
  </ul>
  {% endunless %}{% endfor %}
</div>

In you post layout files put the below code in the footer section

layouts/post.html

<div class="related">
  {% if page.tags != null %}
  <div class="tags">
    <h4>
      {% for tag in page.tags %}
	      <a href="/tags#{{ tag | slugify }}-ref">
          <i class="fa fa-tags"></i>
	          {{ tag | replace: '-', ' ' }}
	      </a> 
      {% endfor %}
    </h4>
  </div>
</div>
  {% endif %}

Add the CSS for the tags

CSS

/*tags page*/

ul.posts {
    list-style-type: none;
    margin-bottom: 2rem;
    padding: 0;
}

ul.posts li span {
    color: silver;
}

.tag-box {
    list-style: none;
    margin: 0;
    padding: 4px 0;
    overflow: hidden;
}

.tag-box.inline li {
    float: left;
    font-size: 14px;
    font-size: 0.875rem;
    line-height: 2.5;
}

.tag-box a {
    padding: 4px 6px;
    margin: 2px;
    background-color: #e6e6e6;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
    text-decoration: none;
}

.tag-box a span {
    vertical-align: super;
    font-size: 10px;
    font-size: 0.625rem;
}

You can test this feature in the tags/archive page on this blog

Justin Kelly

Justin Kelly

Web Developer, Business Analytics, Data Engineer specialising in PHP, ReactJS, Tableau, AWS RedShift and Matillion ETL

Based in Melbourne, Australia

Feel free to contact me justin@kelly.org.au or _justin_kelly

Comments

That is a cool way to organize posts! However, the page is too long and cluttered. Maybe split things up in smaller subpages? or collapse each tag block with JavaScript unless they’re active? Just my two cents. :-)

Justin Kelly

Thanks Daniel, great suggestions! - as a purely tags page its way to long.

I might look at a sub page per tag or similar to reduce the size

Leave a comment

Name Notify me of replies by email.