Apologies as I'm new to Ruby, but I'm trying to add a liquid tag to my template that I can loop over to show a list of the five most popular tags.
For some reason this plugin just outputs a single tag when I use it.
Here is what I put in mu plugin:
module Jekyll
class PopularTags < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
tags = context.registers[:site].tags
return tags.sort_by { |tag, posts| posts.count }
end
end
end
Liquid::Template.register_tag('popular_tags', Jekyll::PopularTags)
Here is what I put in my template:
{% popular_tags %}
It's also possible to do this without plugins, which means that it will work on GitHub Pages.
I'm already doing something similar (without plugins as well) on my blog, where I'm displaying a list of tags with post counts, alphabetically sorted. The source code is here.
It's not much effort to modify this so that it sorts by post count:
{% capture tags %}
{% for tag in site.tags %}
{{ tag[1].size | plus: 1000 }}#{{ tag[0] }}#{{ tag[1].size }}
{% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}
{% for tag in sortedtags reversed %}
{% assign tagitems = tag | split: '#' %}
<li><a href="/tags/#{{ tagitems[1] }}">{{ tagitems[1] }} ({{ tagitems[2] }})</a></li>
{% endfor %}
I guess there's some explanation necessary:
tag[0]
is the name of the tag.tag[1]
is an array with the posts for the tag, so tag[1].size
is the post count.
Basically, we would need to capture something like tag[1].size#tag[0]
, which would result in a string like this:
3#TagWithThreePosts 1#TagWithOnePost 2#TagWithTwoPosts
Then, in the {% assign sortedtags = ...
line, we're splitting that again and sorting it, so the result is a sorted array of strings:
1#TagWithOnePost
2#TagWithTwoPosts
3#TagWithThreePosts
In the final loop, we loop this in reverse (=descending) order, split by #
to get the tag name and the post count, and display the link.
The only problems are tags with 10 and more posts.
Since we're sorting strings, the result of step 2 would look like this:
1#TagWithOnePost
10#TagWithTenPosts
← WRONG ORDER, because it's a string!
2#TagWithTwoPosts
3#TagWithThreePosts
To fix this, I'm adding 1000 to the post count for the purpose of sorting. So 1#...
and 10#...
become 1001#...
and 1010#...
, and they are ordered properly.
I still want to display the actual post number (without 1000 added), so I'm appending it as the third item in the {% capture tags %}
part:
{{ tag[1].size | plus: 1000 }}#{{ tag[0] }}#{{ tag[1].size }}
By the way, I'm linking to a tag page (/tags/#blah
, e.g. all posts for all tags on a single page) which I implemented in a similar fashion as well, described here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With