Last active
August 29, 2015 13:57
-
-
Save macta/9363880 to your computer and use it in GitHub Desktop.
tag_generator.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=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