How to create a tag cloud in Jekyll + Github Pages with or without plugins
Another post in the series “I’m learning Jekyll and teaching it to you, too”.
A good way to find relevant content from a blog is tags. Each post has tags and you can see all the tags and their corresponding posts in a tag cloud. I have built this website using Jekyll. It doesn’t have a built-in support for tag clouds but you can use jekyll-tagging plugin. Unfortunately I’m deploying and hosting this site using Github pages so custom plugins are not supported for security reasons. There are ways to go around this such as Github Actions or jekyll-deploy-action. However, I didn’t want to go this way. I want a simple tag cloud that looks like this
- tag1
- Post1 that uses tag1
- Post2 that uses tag1
- tag2
- Post1 that uses tag2 …
There are many posts about how to build tag clouds and tag sites using Liquid. They are quite neat. But many will rely on a way to actually generate the tagpages like
- https://you.github.io/tag/football
- https://you.github.io/tag/chess
Since those cannot be generated using Liquid (as far as I know) they have to be generated using a Python script that is ran in CI after each commit. It’s a good solution but not for me.
I think an easier way is either:
- Generate a page
/tags/
that has a list of all tags and all posts in the tags - Generate a sidebar to the main page that has a list of all tags and all posts in the tags
I found this solution from here:
{% for tag in site.tags %}
<h3>{{ tag[0] }}</h3>
<ul>
{% for post in tag[1] %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% endfor %}
Meta Bonus: I had to use Liquid raw
to show you above because otherwise it gets processed. Answer here and here.
The resulting tag cloud can be found in here
Tag-related tips and tricks
Get a variable with all the tags
{% assign all_tags = '' | split: ',' %}
{% for post in site.posts %}
{% for tags in post.tags %}
{% for tag in tags %}
{% assign all_tags = all_tags | push: tag %}
{% endfor %}
{% endfor %}
{% endfor %}
{% assign all_tags = all_tags | sort %}
{% assign all_tags = all_tags | uniq %}
Then you can do this
<ul class="tag-list">
{% for tag in all_tags %}
<li><a href="{{ site.tag_dir | prepend: '/' }}/{{ tag | uri_escape }}">{{ tag }}</a></li>
<ul class="posts-per-tag">
{% for post in site.posts %}
{% for tags in post.tags %}
{% for taginner in tags %}
{% if tag == taginner %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
</ul>
{% endfor %}
</ul>
but then you have to create the tag pages yourself.
Github must create automatically the .html
files for all the tag/football
and tag/music
etc pages automatically.
Or you can do them manually but don’t even imagine that you remember to keep it up to date unless you’ll update your page once a month at max.
I will try this in the future but I’m happy with a simple page for now.
How to show tags in post?
I want to show the tags in the post title.
I think the best way is to copy this minima layout to your _layouts/post.html
and edit it.
If you’re using some other theme then find the _layouts/post.html
for your theme.
I edited the part where <header>
is created.