Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Show comment
Hide comment
@friddle

friddle Nov 7, 2013

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

friddle commented Nov 7, 2013

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

@theironsamurai

This comment has been minimized.

Show comment
Hide comment
@theironsamurai

theironsamurai Jun 5, 2014

Ooh! This is awesome. Thank you!

theironsamurai commented Jun 5, 2014

Ooh! This is awesome. Thank you!

@daudich

This comment has been minimized.

Show comment
Hide comment
@daudich

daudich 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.

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

This comment has been minimized.

Show comment
Hide comment
@squito

squito 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

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

This comment has been minimized.

Show comment
Hide comment
@eminaksehirli

eminaksehirli Jan 15, 2015

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>.

eminaksehirli commented Jan 15, 2015

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

This comment has been minimized.

Show comment
Hide comment
@Lewiscowles1986

Lewiscowles1986 Jun 23, 2015

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

Lewiscowles1986 commented Jun 23, 2015

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

This comment has been minimized.

Show comment
Hide comment
@Stargator

Stargator Dec 13, 2015

Is this compatible with Jekyll 3?

Stargator commented Dec 13, 2015

Is this compatible with Jekyll 3?

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