177 lines
6.0 KiB
Ruby
177 lines
6.0 KiB
Ruby
# encoding: utf-8
|
|
#
|
|
# Jekyll category 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 category pages for jekyll sites.
|
|
#
|
|
# Included filters :
|
|
# - category_links: Outputs the list of categories 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 :
|
|
# - category_dir: The subfolder to build category pages in (default is 'categories').
|
|
# - category_title_prefix: The string used before the category name in the page title (default is
|
|
# 'Category: ').
|
|
|
|
require 'stringex'
|
|
|
|
module Jekyll
|
|
|
|
# The CategoryIndex class creates a single category page for the specified category.
|
|
class CategoryIndex < Page
|
|
|
|
# Initializes a new CategoryIndex.
|
|
#
|
|
# +base+ is the String path to the <source>.
|
|
# +category_dir+ is the String path between <source> and the category folder.
|
|
# +category+ is the category currently being processed.
|
|
def initialize(site, base, category_dir, category)
|
|
@site = site
|
|
@base = base
|
|
@dir = category_dir
|
|
@name = 'index.html'
|
|
self.process(@name)
|
|
# Read the YAML data from the layout page.
|
|
self.read_yaml(File.join(base, '_layouts'), 'category_index.html')
|
|
self.data['category'] = category
|
|
# Set the title for this page.
|
|
title_prefix = site.config['category_title_prefix'] || 'Category: '
|
|
self.data['title'] = "#{title_prefix}#{category}"
|
|
# Set the meta-description for this page.
|
|
meta_description_prefix = site.config['category_meta_description_prefix'] || 'Category: '
|
|
self.data['description'] = "#{meta_description_prefix}#{category}"
|
|
end
|
|
|
|
end
|
|
|
|
# The CategoryFeed class creates an Atom feed for the specified category.
|
|
class CategoryFeed < Page
|
|
|
|
# Initializes a new CategoryFeed.
|
|
#
|
|
# +base+ is the String path to the <source>.
|
|
# +category_dir+ is the String path between <source> and the category folder.
|
|
# +category+ is the category currently being processed.
|
|
def initialize(site, base, category_dir, category)
|
|
@site = site
|
|
@base = base
|
|
@dir = category_dir
|
|
@name = 'atom.xml'
|
|
self.process(@name)
|
|
# Read the YAML data from the layout page.
|
|
self.read_yaml(File.join(base, '_includes/custom'), 'category_feed.xml')
|
|
self.data['category'] = category
|
|
# Set the title for this page.
|
|
title_prefix = site.config['category_title_prefix'] || 'Category: '
|
|
self.data['title'] = "#{title_prefix}#{category}"
|
|
# Set the meta-description for this page.
|
|
meta_description_prefix = site.config['category_meta_description_prefix'] || 'Category: '
|
|
self.data['description'] = "#{meta_description_prefix}#{category}"
|
|
|
|
# Set the correct feed URL.
|
|
self.data['feed_url'] = "#{category_dir}/#{name}"
|
|
end
|
|
|
|
end
|
|
|
|
# The Site class is a built-in Jekyll class with access to global site config information.
|
|
class Site
|
|
|
|
# Creates an instance of CategoryIndex for each category page, renders it, and
|
|
# writes the output to a file.
|
|
#
|
|
# +category_dir+ is the String path to the category folder.
|
|
# +category+ is the category currently being processed.
|
|
def write_category_index(category_dir, category)
|
|
index = CategoryIndex.new(self, self.source, category_dir, category)
|
|
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
|
|
|
|
# Create an Atom-feed for each index.
|
|
feed = CategoryFeed.new(self, self.source, category_dir, category)
|
|
feed.render(self.layouts, site_payload)
|
|
feed.write(self.dest)
|
|
# Record the fact that this page has been added, otherwise Site::cleanup will remove it.
|
|
self.pages << feed
|
|
end
|
|
|
|
# Loops through the list of category pages and processes each one.
|
|
def write_category_indexes
|
|
if self.layouts.key? 'category_index'
|
|
dir = self.config['category_dir'] || 'categories'
|
|
self.categories.keys.each do |category|
|
|
self.write_category_index(File.join(dir, category.to_url), category)
|
|
end
|
|
|
|
# Throw an exception if the layout couldn't be found.
|
|
else
|
|
throw "No 'category_index' layout found."
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
# Jekyll hook - the generate method is called by jekyll, and generates all of the category pages.
|
|
class GenerateCategories < Generator
|
|
safe true
|
|
priority :low
|
|
|
|
def generate(site)
|
|
site.write_category_indexes
|
|
end
|
|
|
|
end
|
|
|
|
|
|
# Adds some extra filters used during the category creation process.
|
|
module Filters
|
|
|
|
# Outputs a list of categories as comma-separated <a> links. This is used
|
|
# to output the category list for each post on a category page.
|
|
#
|
|
# +categories+ is the list of categories to format.
|
|
#
|
|
# Returns string
|
|
#
|
|
def category_links(categories)
|
|
dir = @context.registers[:site].config['category_dir']
|
|
categories = categories.sort!.map do |item|
|
|
"<a class='category' href='/#{dir}/#{item.to_url}/'>#{item}</a>"
|
|
end
|
|
|
|
case categories.length
|
|
when 0
|
|
""
|
|
when 1
|
|
categories[0].to_s
|
|
else
|
|
"#{categories[0...-1].join(', ')}, #{categories[-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
|
|
|