Skip to content

Commit

Permalink
lib/jekyll/tagging.rb: Heavy refactoring to better support monkey pat…
Browse files Browse the repository at this point in the history
…ching.

* Dropped "dynamic" Tagger constants; exposed *current* Site object instead.
* Incorporated types in Tagger#new_tag; enabled changing page name and data.
* Dropped Site object from signatures; made internal methods private.
* Extraced Tagger#add_tag_cloud from Tagger#generate.
  • Loading branch information
blackwinter committed Oct 5, 2012
1 parent ddab911 commit 33a9d47
Showing 1 changed file with 48 additions and 45 deletions.
93 changes: 48 additions & 45 deletions lib/jekyll/tagging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,62 @@ class Tagger < Generator

safe true

def generate(site)
%w[TAG_PAGE_DIR TAG_FEED_DIR].each do |dir_name|
unless Tagger.const_defined?(dir_name.to_sym)
Tagger.const_set(dir_name, site.config[dir_name.downcase] || 'tag')
end
end
attr_accessor :site

@tag_page_layout = site.config['tag_page_layout']
@tag_feed_layout = site.config['tag_feed_layout']
@types = [:page, :feed]

unless Jekyll::Filters.const_defined?(:PRETTY_URL)
Jekyll::Filters.const_set('PRETTY_URL', site.permalink_style == :pretty)
end
class << self; attr_accessor :types, :site; end

if @tag_page_layout
generate_tag_pages(site)
else
warn 'WARNING: You have to define a tag_page_layout in configuration file.'
end
def generate(site)
self.class.site = self.site = site

t = { 'tag_data' => calculate_tag_cloud(site) }
site.respond_to?(:add_payload) ? site.add_payload(t) : site.config.update(t)
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(site)
site.tags.each { |tag, posts|
site.pages << new_tag(site, site.source, TAG_PAGE_DIR, tag, posts.sort.reverse, @tag_page_layout)
if @tag_feed_layout
site.pages << new_tag(site, site.source, TAG_FEED_DIR, tag, posts.sort.reverse, @tag_feed_layout)
def generate_tag_pages
site.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 new_tag(site, base, dir, tag, posts, layout)
TagPage.new(site, base, dir, "#{tag}#{site.layouts[layout].ext}", {
'layout' => layout,
'posts' => posts,
})
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

# 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(site, num = 5)
tags = site.tags.map { |tag, posts| [tag.to_s, posts.size] }.sort
range = 1..tags.map { |_, size| size }.max unless tags.empty?
def calculate_tag_cloud(num = 5)
range = 0

tags = site.tags.map { |tag, posts|
[tag.to_s, range < (size = posts.size) ? range = size : size]
}

range = 1..range

tags.map { |tag, size| [tag, range.quantile(size, num)] }
tags.sort!.map! { |tag, size| [tag, range.quantile(size, num)] }
end

end
Expand All @@ -69,14 +73,12 @@ def initialize(site, base, dir, name, data = {})
self.content = data.delete('content') || ''
self.data = data

dir = dir[-1, 1] == '/' ? dir : '/' + dir

super(site, base, dir, name)
super(site, base, dir[-1, 1] == '/' ? dir : '/' + dir, name)

self.data['tag'] = basename
data['tag'] ||= basename
end

def read_yaml(_, __)
def read_yaml(*)
# Do nothing
end

Expand All @@ -86,24 +88,25 @@ module Filters

def tag_cloud(site)
site['tag_data'].map { |tag, set|
tag_link(tag, tag_url(tag), { :class => "set-#{set}" })
tag_link(tag, tag_url(tag), :class => "set-#{set}")
}.join(' ')
end

def tag_link(tag, url = tag_url(tag), html_opts = nil)
unless html_opts.nil?
html_opts = ' ' + html_opts.map { |k, v| %Q{#{k}="#{v}"} }.join(' ')
end
html_opts &&= ' ' << html_opts.map { |k, v| %Q{#{k}="#{v}"} }.join(' ')
%Q{<a href="#{url}"#{html_opts}>#{tag}</a>}
end

def tag_url(tag)
"/#{Tagger::TAG_PAGE_DIR}/#{ERB::Util.u(tag)}#{'.html' unless PRETTY_URL}"
def tag_url(tag, type = :page, site = Tagger.site)
url = File.join('', site.config["tag_#{type}_dir"], ERB::Util.u(tag))
site.permalink_style == :pretty ? url : url << '.html'
end

def tags(obj)
tags = obj['tags'][0].is_a?(Array) ? obj['tags'].map{ |t| t[0] } : obj['tags']
tags.map { |t| tag_link(t, tag_url(t)) if t.is_a?(String) }.compact.join(', ')
tags = obj['tags'].dup
tags.map! { |t| t.first } if tags.first.is_a?(Array)
tags.map! { |t| tag_link(t, tag_url(t)) if t.is_a?(String) }.compact!
tags.join(', ')
end

end
Expand Down

0 comments on commit 33a9d47

Please sign in to comment.