After doing my initial post yesterday I realised it'd be useful to have tags (or categories, whatever your preferred nomenclature) support. It's an easy way for a user to quickly find everything relating to, say, Pretzel without having to read about cats. How do we go about getting such a feature? Remeember that Pretzel is a static blog engine. Everything is generated offline on your computer and then uploaded to your host (in my case, Github Pages) so there's no hitting a database to pull back the relevant files.
If you investigate a little bit you'll find that when you're viewing an individual post the template used to generate the static HTML is _layouts/post.html which seems to have some code relating to tags;
<li><a href="/tag/pretzel">pretzel</a></li>
<li><a href="/tag/blog">blog</a></li>
The default set up has some support for it! Excellent! If you look at the mark down source files for your post you'll see there's a block of YAML at the top (actually this is something Jekyll refers to as Front Matter and is how it determines the file is special and needs processing. Pretzel follows this same convention). We need to add some tags to this block. The Front Matter for this post might be;
---
layout: post
title: "Tags?"
tags: [ pretzel, blog ]
---
This tells Pretzel that this post has two tags associated with it; Pretzel and blog. Let's fire up Pretzel and "taste" things...
Success! I'll just go click on those tag links and...
I should have known that'd be too easy. If you have a look about the place you'll find that there's a plugin for Jekyll to support tags. But that's not that helpful to us. So back to the drawing board. I came across a post on using tags on Github Pages - it seems that Github Pages don't support the tags plugin so Jekyll users are in a similar boat to us. Interesting!
Going through the steps in the Minddust post we can straight away skip the first two - the default Pretzel templates already contain markup for tags. Let's start with creating a new layout. Create a new file _layouts/posts_by_tag.html
and we'll copy the content from Minddust;
<h1>Articles by tag :</h1>
<div>
<p>There are no posts for this tag.</p>
</div>
After a bit of trial and error I found you don't actually need _data/tags.yml
either so ignore that. We do, however, have to create a template-per-tag. This is where such a method will kind of fall down. If you use lots and lots of tags this is the sort of thing that you are (well, I am, anyhow) likely to forget. If you do then your readers will get a 404 when they click on a tag that you haven't "populated" yet. In lieu of a better solution we'll live with this. Now we'll create our first tag layout file - for me that's tag/blog.md
. (Note: The tag
portion is because our URLs will be of the form tag/blog
- if you wanted these to be of the form my-awesome-tags/blog
your blog.md
would instead live in the my-awesome-tags
directory. Jekyll / Pretzel will copy directories from the input to the output unless they start with an underscore).
---
layout: posts_by_tag
tag: blog
permalink: /tag/blog
---
Nothing else is needed in our layout file. A couple of notes; the layout
value should be the filename of your layout file, without the path or extension, that you created earlier (eg. I have _layouts/posts_by_tag.html
so this value is posts_by_tag
). The permalink
tag here just sets the output URL to be used. I want to serve my tag page as /tag/blog
instead of the default /tag/blog.html
.) Now that that's done let's test it out!
... And apparently I have even fewer blog posts than I thought! The good news is we aren't getting a 404 anymore. The bad news is... we're not getting our nice list of posts for the tag. What gives? I did a little digging and it turns out it's the syntax of the layout file. Whilst Pretzel is largely compatible with Jekyll it isn't 100% so. The way it does tags is one of those differences. In Jekyll it seems like it's a dictionary of tag names to posts. However in Pretzel tags are a list of tag items each of which has the name of the tag and all of the posts for that tag. (Side note: I believe Categories work the same way). So our copy-pasta'd layout file just isn't going to cut it.
<h1>Posts by tag </h1>
<div>
<p>There's no posts for ""!</p>
</div>
First off we're going to set a variable HasTag
to false
. We'll then loop through all of the tags
that have been used on our site and compare the Name
to the tag
the user is currently looking at. If they match we set HasTag
to true
and loop through all of the Posts
on the tag
and output a link to the post using it's title. Finally if HasTag
is still false
we can print out "No tags found" style message. Now let's try again...
... And it works! It's not pretty but it's a list of all my posts. Now why does this look so bland compared to the rest of the posts (not that they're terribly pretty, but still!). If you snoop about your setup you'll see there's _layouts/layout.html
which has all the base styling for your site. When you look at the default _layouts/post.html
you'll see at the top it has
---
layout: layout
---
It might look a little redundant but it's actually saying "Inherit the layout
for this file from the file stored at _layouts/
layout
.html
". So, we just need to add a similar tag to our posts_by_tag.html
;
---
layout: layout
---
<h1>Posts by tag </h1>
<div>
<p>There's no posts for ""!</p>
</div>
And that's about it! Have a look through the list of Liquid Variables for other details you may wish to include on your listing page (such as the post.date
). And finally don't forget you'll need to go through and create a corresponding .md
file in tag
for each tag you use on your site. In the future I'll look at seeing if this is something I can automate as I'm not one for doing something a computer will do much more reliably.