Search code examples
rubyjekyll

How do you sort site.tags by post count in Jekyll?


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 %}

Solution

  • Well actually, from what I'm currently reading, the Tag plugins in Jekyll should be used just like a tag and not like a variable. So in that case, you should indeed use this in your template :

    {% popular_tags %}
    

    But it's the behaviour of your class that seems to be wrong. It should not return a variable/hash, it should return the HTML code that will be displayed in stead of the popular_tags tag.

    For instance, here's something you could be doing :

    module Jekyll
      class PopularTags < Liquid::Tag
    
        def initialize(tag_name, text, tokens)
          super
        end
    
        def render(context)
          tags = context.registers[:site].tags
    
          html = "<ul>"
          sorted = tags.sort_by { |t,posts| posts.count }
          sorted.each do |t, posts|
            html << "<li>TAG: #{t} (#{posts.count})</li>"
          end
          html << "</ul>"
    
          html
        end
      end
    end
    
    Liquid::Template.register_tag('popular_tags', Jekyll::PopularTags)
    

    Hope this helps. I just tried it and it's working as intended. If you want to display the most used tags first, just change the sort_by line, and use -posts.count instead of posts.count.

    You can have a look at this other plugin source code, might help you.