Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag cloud #282

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .themes/classic/source/_includes/asides/tag_cloud.html
@@ -0,0 +1,4 @@
<section class="tag-cloud">
<h1>Tags</h1>
{% tag_cloud %}
</section>
17 changes: 17 additions & 0 deletions .themes/classic/source/_layouts/tag_index.html
@@ -0,0 +1,17 @@
---
layout: page
footer: false
---

<div id="blog-archives" class="tag">
{% for post in site.tags[page.tag] %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% unless year == this_year %}
{% assign year = this_year %}
<h2>{{ year }}</h2>
{% endunless %}
<article>
{% include archive_post.html %}
</article>
{% endfor %}
</div>
3 changes: 2 additions & 1 deletion _config.yml
Expand Up @@ -32,6 +32,7 @@ destination: public
plugins: plugins
code_dir: downloads/code
category_dir: blog/categories
tag_dir: blog/tags
markdown: rdiscount
pygments: false # default python pygments have been replaced by pygments.rb

Expand All @@ -44,7 +45,7 @@ titlecase: true # Converts page and post titles to tilecase

# list each of the sidebar modules you want to include, in the order you want them to appear.
# To add custom asides, create files in /source/_includes/custom/asides/ and add them to the list like 'custom/asides/custom_aside_name.html'
default_asides: [asides/recent_posts.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html]
default_asides: [asides/recent_posts.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html, asides/tag_cloud.html]

# Each layout uses the default asides, but they can have their own asides instead. Simply uncomment the lines below
# and add an array with the asides you want to use.
Expand Down
48 changes: 48 additions & 0 deletions plugins/tag_cloud.rb
@@ -0,0 +1,48 @@
module Jekyll
class TagCloud < Liquid::Tag

CLOUD_MAX_RANKS = 5;
CLOUD_SIZE = 100;

def render(context)
s = StringIO.new
begin
tags = context['site']['tags']
unless tags.nil?
sorted = tags.sort {|a, b| b[1].length <=> a[1].length}
factor = 1
max_count = sorted[0][1].length
min_count = sorted[-1][1].length

if max_count == min_count
min_count -= CLOUD_MAX_RANKS
else
factor = (CLOUD_MAX_RANKS - 1) / Math.log(max_count - min_count + 1)
end

if sorted.length < CLOUD_MAX_RANKS
factor *= sorted.length / CLOUD_MAX_RANKS.to_f
end

for index in (0..CLOUD_SIZE).to_a.shuffle do
if sorted[index].nil?
next
end

dir = context['site']['tag_dir'] || 'tag'
rank = CLOUD_MAX_RANKS - (Math.log(sorted[index][1].length - min_count + 1) * factor).to_i
s << "<span class='rank-#{rank}'>"
s << "<a href='/#{dir}/#{sorted[index][0].gsub(/_|\W/, '-')}'>#{sorted[index][0]}</a>"
s << "</span> "
end
end
rescue => boom
# Nothing, I think
p boom
end
s.string
end
end
end

Liquid::Template.register_tag('tag_cloud', Jekyll::TagCloud)
136 changes: 136 additions & 0 deletions plugins/tag_generator.rb
@@ -0,0 +1,136 @@
# Jekyll tag page generator.
# http://recursive-design.com/projects/jekyll-plugins/
#
# Version: 0.1.4 (201101061053)
#
# Copyright (c) 2010 Dave Perrett, http://recursive-design.com/
# Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
#
# A generator that creates tag pages for jekyll sites.
#
# Included filters :
# - tag_links: Outputs the list of tags as comma-separated <a> links.
# - date_to_html_string: Outputs the post.date as formatted html, with hooks for CSS styling.
#
# Available _config.yml settings :
# - tag_dir: The subfolder to build tag pages in (default is 'tags').
# - tag_title_prefix: The string used before the tag name in the page title (default is
# 'Tag: ').
module Jekyll


# The TagIndex class creates a single tag page for the specified tag.
class TagIndex < Page

# Initializes a new TagIndex.
#
# +base+ is the String path to the <source>.
# +tag_dir+ is the String path between <source> and the tag folder.
# +tag+ is the tag currently being processed.
def initialize(site, base, tag_dir, tag)
@site = site
@base = base
@dir = tag_dir
@name = 'index.html'
self.process(@name)
# Read the YAML data from the layout page.
self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
self.data['tag'] = tag
# Set the title for this page.
title_prefix = site.config['tag_title_prefix'] || 'Tag: '
self.data['title'] = "#{title_prefix}#{tag}"
# Set the meta-description for this page.
meta_description_prefix = site.config['tag_meta_description_prefix'] || 'Tag: '
self.data['description'] = "#{meta_description_prefix}#{tag}"
end

end


# The Site class is a built-in Jekyll class with access to global site config information.
class Site

# Creates an instance of TagIndex for each tag page, renders it, and
# writes the output to a file.
#
# +tag_dir+ is the String path to the tag folder.
# +tag+ is the tag currently being processed.
def write_tag_index(tag_dir, tag)
index = TagIndex.new(self, self.source, tag_dir, tag)
index.render(self.layouts, site_payload)
index.write(self.dest)
# Record the fact that this page has been added, otherwise Site::cleanup will remove it.
self.pages << index
end

# Loops through the list of tag pages and processes each one.
def write_tag_indexes
if self.layouts.key? 'tag_index'
dir = self.config['tag_dir'] || 'tag'
self.tags.keys.each do |tag|
self.write_tag_index(File.join(dir, tag.gsub(/_|\W/, '-')), tag)
end

# Throw an exception if the layout couldn't be found.
else
throw "No 'tag_index' layout found."
end
end

end


# Jekyll hook - the generate method is called by jekyll, and generates all of the tag pages.
class GenerateTags < Generator
safe true
priority :low

def generate(site)
site.write_tag_indexes
end

end


# Adds some extra filters used during the tag creation process.
module Filters

# Outputs a list of tags as comma-separated <a> links. This is used
# to output the tag list for each post on a tag page.
#
# +tags+ is the list of tags to format.
#
# Returns string
#
def tag_links(tags)
dir = @context.registers[:site].config['tag_dir']
tags = tags.sort!.map do |item|
"<a class='tag' href='/#{dir}/#{item.gsub(/_|\W/, '-')}/'>#{item}</a>"
end

case tags.length
when 0
""
when 1
tags[0].to_s
else
"#{tags[0...-1].join(', ')}, #{tags[-1]}"
end
end

# Outputs the post.date as formatted html, with hooks for CSS styling.
#
# +date+ is the date object to format as HTML.
#
# Returns string
def date_to_html_string(date)
result = '<span class="month">' + date.strftime('%b').upcase + '</span> '
result += date.strftime('<span class="day">%d</span> ')
result += date.strftime('<span class="year">%Y</span> ')
result
end

end

end