Tuning the blog - 2) adding categories and tags

I have always been one to flit from subject to subject - both inside and outside a work environment, life is generally like that. Given that a blog (with a little cheating here and there) is generally written chronologically, I feel the need to be able to identify themes and topics so that all the stuff on a single subject can be gathered together for a comprehensive read (if only by me).

Categories and tags

Whilst I have often come across Categories and Tags in previous blogging, I have not been entirely clear what they are. A quick trip to Google found this on WordPress

Although that is not a rigourous definition, it is good enough for me and one thta I will bear in mind.

Adding categories and tags to Jekyll

The Jekyll starting point that I chose does not have categories or tags so a bit of research was needed. The relevant documentation seemed to me to vary between non-existant and opaque, so I opted to look at some Jekyll blogs on GitHub. Two things suprised me:

  • how many blogs there were
  • how few of them used categories or tags

I eventually found a few sites that used them and this led me to four points of investigation

  • how do you specify categories and tags in a post? Dealt with in this post
  • how (if at all) do you display the categories and tags attached to a post? Dealt with in this post
  • how do you display category and tag based lists of posts? To be dealt with in a later post
  • how do you direct visitors to the category and tag based lists of posts? * partially dealt with in this post*

Specifying tags and categories in a post

This is the easy one. Put entries in the Front Matter like this:

category: blogging
tags: [jekyll,categories,tags,frontmatter,github-pages]

The second of these can also be entered in this format with the same results:

tags: 
- jekyll
- categories
- tags
- frontmatter
- github-pages

Displaying the categories and tags attached to a post

This is much more complex and defeated me for several hours until I came across this post from Stephan Groß

Even then it took me several goes to get it right. Here is what I did

  1. I replaced the content of _layouts/my post.html with this (derived largely from Stephan’s site)
{% assign post = page %}
<article>
    <header id="post-header">
        <h1 id="post-title">{{ post.title }}</h1>
        <h4 id="post-subtitle"><time datetime="{{ post.date | date_to_xmlschema }}"></time></h4> 
    </header>
    <div id="post-content">
        {{ content }}
        {% if post.category %}
            {% for site_category in site.data.categories %}
                {% if site_category.slug == post.category %}
                    {% assign category = site_category %}
                {% endif %}
            {% endfor %}
            {% if category %}
                {% capture category_content %} in <span class="label" style="background-color:{{ category.color }}"><a href="/blog/category/{{ category.slug }}/">{{ category.name }}</a></span>{% endcapture %}
            {% endif %}
        {% else %}
            {% assign category_content = '' %}
        {% endif %}
        {% if post.tags.size > 0 %}
            {% capture tags_content %} with {% if post.tags.size == 1 %}{% else %}<i class="fa fa-tags"></i>{% endif %}: {% endcapture %}
            {% for post_tag in post.tags %}
                {% for data_tag in site.data.tags %}
                    {% if data_tag.slug == post_tag %}
                        {% assign tag = data_tag %}
                    {% endif %}
                {% endfor %}
                {% if tag %}
                    {% capture tags_content_temp %}{{ tags_content {{<a href="/blog/tag/{{ tag.slug }}/">{{ tag.name }}</a>{% if forloop.last == false %}, {% endif %}{% endcapture %}
                    {% assign tags_content = tags_content_temp %}
                {% endif %}
            {% endfor %}
        {% else %}
            {% assign tags_content = '' %}
        {% endif %}
        <p id="post-meta">Posted {{ category_content }}{{ tags_content }}</p>
        <div class="date">
            Written on {{ page.date | date: "%B %e, %Y at %R" }}
        </div>
    </div>
</article>

2. I created a file _data/tags.yml and put something like this in it:

- slug: github-pages
name: GitHub Pages
- slug: jekyll
name: Jekyll
- slug: categories
name: Categories
- slug: tags
name: Tags
- slug: frontmatter
name: Front Matter 

The lines in this file occur in pairs. The first line in each pair contains - slug: followed by a space and the name of the tag (which needs to be a single word}. This is the tag that will be placed in the Front Matter section at the beginning of a post. The second line in each pair consists of name: followed by a space and the full name of the tag. This will appear at the foot of the post (as set up here, but it could be anywhere in the post or nowhere at all).

3. I created a file _data/categories.yml and put something like this in it:

- slug: blogging
name: Blogging
color: '#3498db'

- slug: starting
name: Getting Started
color: '#1abc9c'

The lines of this file appear in groups of three with a blank line between each group (I have to confess that at the time of writing I’m not sure wether the blank line is necessary). The first line in each pair contains - slug: followed by a space and the name of the category (which needs to be a single word}. This is the category that will be placed in the Front Matter section at the beginning of a post. The second line in each pair consists of name: followed by a space and the full name of the category. This will appear at the foot of the post (as set up here, but it could be anywhere in the post or nowhere at all). The third line consists of color: followed by a space and an rgb colour code in the form '#rrggbb' where rr , gg and bb are the hexidecimal values of th red, green and blue components. This colour is used as the background colour when the category is displayed in the post.

The line:

 <p id="post-meta">Posted {{ category_content }}{{ tags_content }}</p>

from step 1. above is what creates the list of tags and categories at the end of the post (as can be seen below. It is important to note that categories and tags wil not appear unless they are included in the files from steps 2 and 3 above.

At this stage of customisation, the category and tags are clickable, but they don’t lead anywhere. Creating category and tag pages will be the subject of my next post.

Posted in Blogging with : Jekyll, Categories, Tags, Front Matter

Written on January 4, 2015 at 13:20