Skip to content

Instantly share code, notes, and snippets.

@ilkka
Created November 22, 2010 20:07
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save ilkka/710577 to your computer and use it in GitHub Desktop.
Save ilkka/710577 to your computer and use it in GitHub Desktop.
Jekyll tag cloud / tag pages plugin
module Jekyll
class TagCloudTag < Liquid::Tag
safe = true
def initialize(tag_name, text, tokens)
super
end
def render(context)
html = ""
tags = context.registers[:site].tags
avg = tags.inject(0.0) {|memo, tag| memo += tag[1].length} / tags.length
weights = Hash.new
tags.each {|tag| weights[tag[0]] = tag[1].length/avg}
tags.each do |tag, posts|
html << "<span style='font-size: #{sprintf("%d", weights[tag] * 100)}%'><a href='/tags/#{tag}/'>#{tag}</a></span>\n"
end
html
end
end
end
Liquid::Template.register_tag('tag_cloud', Jekyll::TagCloudTag)
module Jekyll
class TagPage
include Convertible
attr_accessor :site, :pager, :name, :ext
attr_accessor :basename, :dir, :data, :content, :output
def initialize(site, tag, posts)
@site = site
@tag = tag
self.ext = '.html'
self.basename = 'index'
self.content = <<-EOS
{% for post in page.posts %}
<h3>{{ post.date | date: "%A %d.%m." }} &mdash; <a href="{{ post.url }}">{{ post.title }}</a></h3>
<p>{{ post.content | truncatewords: 20 }}</p>
<p>
{% if post.categories != empty %}
In {{ post.categories | array_to_sentence_string }}.
{% endif %}
{% if post.tags != empty %}
Tagged {{ post.tags | array_to_sentence_string }}.
</p>
{% endif %}
{% endfor %}
EOS
self.data = {
'layout' => 'default',
'type' => 'tag',
'title' => "Posts tagged #{@tag}",
'posts' => posts
}
end
def render(layouts, site_payload)
payload = {
"page" => self.to_liquid,
"paginator" => pager.to_liquid
}.deep_merge(site_payload)
do_layout(payload, layouts)
end
def url
File.join("/tags", @tag, "index.html")
end
def to_liquid
self.data.deep_merge({
"url" => self.url,
"content" => self.content
})
end
def write(dest_prefix, dest_suffix = nil)
dest = dest_prefix
dest = File.join(dest, dest_suffix) if dest_suffix
path = File.join(dest, CGI.unescape(self.url))
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write(self.output)
end
end
def html?
true
end
end
end
module Jekyll
class TagPageGenerator < Generator
safe true
def generate(site)
site.tags.each do |tag, posts|
site.pages << TagPage.new(site, tag, posts)
end
end
end
end
@friddle
Copy link

friddle commented Nov 7, 2013

Can you post a tutorial?
I am new to Jekyll.thanks.

@theironsamurai
Copy link

Ooh! This is awesome. Thank you!

@daudich
Copy link

daudich commented Jul 29, 2014

Is their a tutorial available for this somewhere? or maybe even if you could add some comments to the files as to how to actually use it that would be great. Currently this plugin does not work for me. Nothing is being generated.

@squito
Copy link

squito commented Oct 27, 2014

To get this to work w/ ruby 2.1.3 & jekyll 2.4.0, I had to change the calls to foo.deep_merge(xxx) to Utils.deep_merge_hashes(foo,xxx). I don't really know any ruby, just following the discussion here:
moshen/jekyll-asset_bundler#22
and this patch:
moshen/jekyll-asset_bundler@d8c2211

@eminaksehirli
Copy link

For Jekyll 2.5.3, change the line class TagPage in tag_page.rb with class TagPage < Page in addition to @squito's comment to get rid of the Error: undefined method 'destination' for #<Jekyll::TagPage:0x000000020a3730>.

@Lewiscowles1986
Copy link

for tag_cloud_tag.rb, why not use a layout / include

{% assign all_tags = site.tags|size %}
<div class="tagcloud">{% for tag in site.tags %}
    {% assign tag_name = tag|first %}
    {% assign tag_count = tag|last|size %}
    {% assign tag_avg = tag_count | div: all_tags %}
    <span class="tag" style="font-size: {{ tag_avg | times: 100 }}%;">{{ tag_name }}</span>{% if false %} ({{ tag_count }}){% endif %}
{% endfor %}</div>

Works for me, and you can, as you can probably see; have a tag count added to data attribute or echoed out etc...

RE: links, it's a lovely concept, but I think the links should be a separate plugin to the tag cloud itself, as it actually needs to generate pages, and also, it probably needs a /tags/ folder, so feel free to modify my category listing page plugin, which does the same for category pages.

Better Jekyll Category Pages

@Stargator
Copy link

Is this compatible with Jekyll 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment