So the migration of my blog is now complete, and for the most part it was pretty easy. One of the things I did find tricky was getting the tag cloud to work. This post isn’t meant as a guide for how to do so yourself, but as a breakdown of the process I went through, and why I made some of the choices that I made. I doubt I have the best solution, but it’s close to what I wanted.

The first thing I did was google “tag cloud jekyll” and this came up with lots of different guides on how to build a tag cloud in jekyll, but following them didn’t get me a satisfactory result, they either didn’t output anything, or their output was meaningless. I’m willing to accept I was doing something wrong, but I wanted a tag cloud, so I decided to break down what I wanted. Previously the tag cloud on my blog took the most commonly used tags, and sorted them into one of 5 classes which gave them a different fontsize dependent on how much they’re used. I wanted something similar. Rather than going to the effort of sorting them into 5 groups though I decided to just pick the font size based on the tags usage. So I needed someway of determining how much the tags were used.

So the first thing I wanted to do is determine the average amount a tag is used, mathmatically this is simply the total number of tags divided by the number of unique tags, however when I started this I only knew how to get the number of unique tags, {{ site.tags.size }} where “site.tags” is an array of the unique site tags.

As I had an array of the unique tags I knew I could itterate over them with something like the following

{% for tag in site.tags %}
{% do something with tag here %}
{% endfor %}

I ended up using two of these for loops, one to determine the total number of tags, and the other to output the tag cloud. The first thing I tried was outputing {{ tag.size }} but found that this was always 2. It turned out that each tag in “site.tags” was itself an array, that always contained 2 items. It didn’t take long to find out that “tag[0]” was the title of the tag. What took me longer to work out was that “tag[1]” was another array, this time of all the posts using that tag. This proved to be useful, I could count how many posts each tag was used in, and add them up for the total number of tags used. This gave me

{% assign total_tags = 0 %}
{% for tag in site.tags %}
{% assign total_tags = total_tags | plus: tag[1].size %}
{% endfor %}

So now I just had to make use of this variable. I wanted a tag that matched the average to have a font size of 100%, and a more heavily used tag to be bigger, and a lesser used tag to be smaller, the maths of this should be simple “amount the tag is used”/”average tag usage”x”100”, using the variables we have this would be “tag[1].size”/(“total_tags”/”site.tags.size”)x”100”. I wanted to rearrange this so that I didn’t need the brackets. Fortunately dividing by a fraction, we can multiply by the denominator, giving us “tag[1].size”x”site.tags.size”/”total_tags”x”100”. The maths function in jekyll unfortunately only appeared to work with whole numbers, so I needed to move the division to as late in the equation as possible. This gave me

{% for tag in site.tags %}
{{ tag[1].size | times: site.tags.size | times: 100 | divided_by: total_tags }}
{% endfor %}

This gave me a number, to represent the font size, which needed wrapping in the relevant html code

{% for tag in site.tags %}
<a href="/blog/tags/{{ tag[0] }}" style="font-size:{{ tag[1].size | times: site.tags.size | times: 100 | divided_by: total_tags }}%">{{ tag[0] }}</a>
{% endfor %}

Alas this resulted in the lesser used tags were far too small, and the more used tags were far too big, after playing with some different numbers I settled on multiplying by 25 instead of 100, and then adding 50 to make the smallest tags more legible, meaning the font size became “{{ tag[1].size | times: site.tags.size | times: 25 | divided_by: total_tags | plus: 50 }}”. I also chose to exclude tags used just once from the tag cloud.

posted at 4:24 pm on 9 Nov 2018 by Craig Stewart

Tags:web not-a-designer