Skip to content

Instantly share code, notes, and snippets.

@macta
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macta/9363880 to your computer and use it in GitHub Desktop.
Save macta/9363880 to your computer and use it in GitHub Desktop.
tag_generator.rb
=begin
Jekyll tag page generator.
based on: https://github.com/pattex/jekyll-tagging (v0.5.0)
By Arne Eilermann <eilermann@lavabit.com> and Jens Wille <jens.wille@uni-koeln.de>
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
A generator that creates tag pages for jekyll sites.
Available _config.yml settings :
- tag_page_dir: The subfolder to build category pages in (default is 'categories').
- tag_page_layout: The layout of the tag page
History
4/Mar/2014 - t mackinnon
- converted to a simple plugin you can just copy to ./plugins directory for octopress
with no additional requires
- changed "tag_url" to not begin with leading / so expand_urls can detect it and expand accordingly
- added parameter to tag_cloud to specify the style name of tags
=end
require 'stringex'
require 'cgi'
module Jekyll
class Tagger < Generator
safe true
attr_accessor :site
@types = [:page, :feed]
class << self; attr_accessor :types, :site; end
def generate(site)
self.class.site = self.site = site
generate_tag_pages
add_tag_cloud
end
private
# Generates a page per tag and adds them to all the pages of +site+.
# A <tt>tag_page_layout</tt> have to be defined in your <tt>_config.yml</tt>
# to use this.
def generate_tag_pages
active_tags.each { |tag, posts| new_tag(tag, posts) }
end
def new_tag(tag, posts)
self.class.types.each { |type|
if layout = site.config["tag_#{type}_layout"]
data = { 'layout' => layout, 'posts' => posts.sort.reverse! }
name = yield data if block_given?
site.pages << TagPage.new(
site, site.source, site.config["tag_#{type}_dir"],
"#{name || tag}#{site.layouts[data['layout']].ext}", data
)
end
}
end
def add_tag_cloud(num = 5, name = 'tag_data')
s, t = site, { name => calculate_tag_cloud(num) }
s.respond_to?(:add_payload) ? s.add_payload(t) : s.config.update(t)
end
def quantile(range, value, order = 100)
value < range.first ? 1 : value >= range.last ? order :
((value - range.first) / ((range.last - range.first) / order.to_f)).to_i + 1
end
# Calculates the css class of every tag for a tag cloud. The possible
# classes are: set-1..set-5.
#
# [[<TAG>, <CLASS>], ...]
def calculate_tag_cloud(num = 5)
limit = 0
tags = active_tags.map { |tag, posts|
[tag.to_s, limit < (size = posts.size) ? limit = size : size]
}
range = 1..limit
tags.sort!.map! { |tag, size| [tag, quantile(range, size, num)] }
end
def active_tags
return site.tags unless site.config["ignored_tags"]
site.tags.reject { |t| site.config["ignored_tags"].include? t[0] }
end
end
class TagPage < Page
def initialize(site, base, dir, name, data = {})
self.content = data.delete('content') || ''
self.data = data
super(site, base, dir[-1, 1] == '/' ? dir : '/' + dir, name)
data['tag'] ||= basename
end
def read_yaml(*)
# Do nothing
end
end
module Filters
def tag_cloud(site, style = 'set-')
active_tag_data.map { |tag, set|
tag_link(tag, tag_url(tag), :class => "#{style}#{set}")
}.join(' ')
end
def tag_link(tag, url = tag_url(tag), html_opts = nil)
html_opts &&= ' ' << html_opts.map { |k, v| %Q{#{k}="#{v}"} }.join(' ')
%Q{<a href="#{url}"#{html_opts}>#{tag}</a>}
end
def tag_url(tag, type = :page, site = Tagger.site)
url = File.join(site.config["tag_#{type}_dir"], CGI.escape(tag))
site.permalink_style == :pretty ? url : url << '.html'
end
def tags(obj)
tags = obj['tags'].dup
tags.map! { |t| t.first } if tags.first.is_a?(Array)
tags.map! { |t| tag_link(t, tag_url(t), :rel => 'tag') if t.is_a?(String) }.compact!
tags.join(', ')
end
def active_tag_data(site = Tagger.site)
return site.config['tag_data'] unless site.config["ignored_tags"]
site.config["tag_data"].reject { |tag, set| site.config["ignored_tags"].include? tag }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment