mirror of
https://github.com/WatchOutNewsAgency/wona.github.com.git
synced 2026-01-01 01:16:26 +00:00
1. Moved _plugins into themes/classic/_plugins
I think it's probably better to ship plugins with themes to make it easier to update them. 2. Improved 'install' rake task and made nicer output
This commit is contained in:
109
themes/classic/_plugins/blockquote.rb
Normal file
109
themes/classic/_plugins/blockquote.rb
Normal file
@ -0,0 +1,109 @@
|
||||
#
|
||||
# Author: Josediaz Gonzalez - https://github.com/josegonzalez
|
||||
# Source URL: https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/blockquote.rb
|
||||
# Modified by Brandon Mathis
|
||||
#
|
||||
require './_plugins/titlecase.rb'
|
||||
module Jekyll
|
||||
|
||||
# Outputs a string with a given attribution as a quote
|
||||
#
|
||||
# {% blockquote John Paul Jones %}
|
||||
# Monkeys!
|
||||
# {% endblockquote %}
|
||||
# ...
|
||||
# <blockquote>
|
||||
# Monkeys!
|
||||
# <br />
|
||||
# John Paul Jones
|
||||
# </blockquote>
|
||||
#
|
||||
class Blockquote < Liquid::Block
|
||||
FullCiteWithTitle = /([\w\s]+)(https?:\/\/)(\S+\s)([\w\s]+)/i
|
||||
FullCite = /([\w\s]+)(https?:\/\/)(\S+)/i
|
||||
Author = /([\w\s]+)/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@by = nil
|
||||
@source = nil
|
||||
@title = nil
|
||||
if markup =~ FullCiteWithTitle
|
||||
@by = $1
|
||||
@source = $2 + $3
|
||||
@title = $4.titlecase
|
||||
elsif markup =~ FullCite
|
||||
@by = $1
|
||||
@source = $2 + $3
|
||||
elsif markup =~ Author
|
||||
@by = $1
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
output = super
|
||||
if @by.nil?
|
||||
'<blockquote><p>' + output.join + '</p></blockquote>'
|
||||
elsif !@title.nil?
|
||||
'<blockquote><p>' + output.join + '</p></blockquote>' + '<p><cite><strong>' + @by + '</strong>' + '<a class="source" href="' + @source + '">' + @title + '</a></cite></p>'
|
||||
elsif !@source.nil?
|
||||
'<blockquote><p>' + output.join + '</p></blockquote>' + '<p><cite><strong>' + @by + '</strong>' + '<a class="source" href="' + @source + '">source</a></cite></p>'
|
||||
else
|
||||
'<blockquote><p>' + output.join + '</p></blockquote>' + '<p><cite><strong>' + @by + '</strong></cite></p>'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Outputs a string with a given attribution as a pullquote
|
||||
#
|
||||
# {% blockquote John Paul Jones %}
|
||||
# Monkeys!
|
||||
# {% endblockquote %}
|
||||
# ...
|
||||
# <blockquote class="pullquote">
|
||||
# Monkeys!
|
||||
# <br />
|
||||
# John Paul Jones
|
||||
# </blockquote>
|
||||
#
|
||||
class Pullquote < Liquid::Block
|
||||
FullCiteWithTitle = /([\w\s]+)(http:\/\/|https:\/\/)(\S+)([\w\s]+)/i
|
||||
FullCite = /([\w\s]+)(http:\/\/|https:\/\/)(\S+)/i
|
||||
Author = /([\w\s]+)/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@by = nil
|
||||
@source = nil
|
||||
@title = nil
|
||||
if markup =~ FullCiteWithTitle
|
||||
@by = $1
|
||||
@source = $2 + $3
|
||||
@title = $4
|
||||
elsif markup =~ FullCite
|
||||
@by = $1
|
||||
@source = $2 + $3
|
||||
elsif markup =~ Author
|
||||
@by = $1
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
output = super
|
||||
if @by.nil?
|
||||
'<blockquote class="pullquote"><p>' + output.join + '</p></blockquote>'
|
||||
elsif @title
|
||||
'<blockquote class="pullquote"><p>' + output.join + '</p></blockquote>' + '<p><cite><strong>' + @by + '</strong>' + ' <a class="source" href="' + @source + '">' + @title + '</a></cite></p>'
|
||||
elsif @source
|
||||
'<blockquote class="pullquote"><p>' + output.join + '</p></blockquote>' + '<p><cite><strong>' + @by + '</strong>' + ' <a class="source" href="' + @source + '">source</a></cite></p>'
|
||||
elsif @by
|
||||
'<blockquote class="pullquote"><p>' + output.join + '</p></blockquote>' + '<p><cite><strong>' + @by + '</strong></cite></p>'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('blockquote', Jekyll::Blockquote)
|
||||
Liquid::Template.register_tag('pullquote', Jekyll::Pullquote)
|
||||
|
||||
|
||||
65
themes/classic/_plugins/category.rb
Normal file
65
themes/classic/_plugins/category.rb
Normal file
@ -0,0 +1,65 @@
|
||||
module Jekyll
|
||||
|
||||
class CategoryIndex < Page
|
||||
def initialize(site, base, dir, category)
|
||||
@site = site
|
||||
@base = base
|
||||
@dir = dir
|
||||
@name = 'index.html'
|
||||
|
||||
self.process(@name)
|
||||
self.read_yaml(File.join(base, '_layouts'), 'category_index.html')
|
||||
self.data['category'] = category
|
||||
|
||||
category_title_prefix = site.config['category_title_prefix'] || 'Category: '
|
||||
self.data['title'] = "#{category_title_prefix}#{category}"
|
||||
end
|
||||
end
|
||||
|
||||
class CategoryList < Page
|
||||
def initialize(site, base, dir, categories)
|
||||
@site = site
|
||||
@base = base
|
||||
@dir = dir
|
||||
@name = 'index.html'
|
||||
|
||||
self.process(@name)
|
||||
self.read_yaml(File.join(base, '_layouts'), 'category_list.html')
|
||||
self.data['categories'] = categories
|
||||
end
|
||||
end
|
||||
|
||||
class CategoryGenerator < Generator
|
||||
safe true
|
||||
|
||||
def generate(site)
|
||||
if site.layouts.key? 'category_index'
|
||||
dir = site.config['category_dir'] || 'categories'
|
||||
site.categories.keys.each do |category|
|
||||
write_category_index(site, File.join(dir, category.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase), category)
|
||||
end
|
||||
end
|
||||
|
||||
if site.layouts.key? 'category_list'
|
||||
dir = site.config['category_dir'] || 'categories'
|
||||
write_category_list(site, dir, site.categories.keys.sort)
|
||||
end
|
||||
end
|
||||
|
||||
def write_category_index(site, dir, category)
|
||||
index = CategoryIndex.new(site, site.source, dir, category)
|
||||
index.render(site.layouts, site.site_payload)
|
||||
index.write(site.dest)
|
||||
site.static_files << index
|
||||
end
|
||||
|
||||
def write_category_list(site, dir, categories)
|
||||
index = CategoryList.new(site, site.source, dir, categories)
|
||||
index.render(site.layouts, site.site_payload)
|
||||
index.write(site.dest)
|
||||
site.static_files << index
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
1
themes/classic/_plugins/compass_compiler.rb
Normal file
1
themes/classic/_plugins/compass_compiler.rb
Normal file
@ -0,0 +1 @@
|
||||
system "compass compile --css-dir source/stylesheets"
|
||||
59
themes/classic/_plugins/custom_filters.rb
Normal file
59
themes/classic/_plugins/custom_filters.rb
Normal file
@ -0,0 +1,59 @@
|
||||
#custom filters for Octopress
|
||||
|
||||
module OctopressFilters
|
||||
def exerpt(input, url, url_text="Reade more…", permalink_text=false)
|
||||
if input.index(/<!--\s?more\s?-->/i)
|
||||
input.split(/<!--\s?more\s?-->/i)[0] + "<p><a href='#{url}'>#{url_text}</a></p>"
|
||||
elsif permalink_text
|
||||
input + "<p><a href='#{url}'>#{permalink_text}</a></p>"
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
def full_urls(input, url='')
|
||||
input.gsub /(\s+(href|src)\s*=\s*["|']{1})(\/[^\"'>]+)/ do
|
||||
$1+url+$3
|
||||
end
|
||||
end
|
||||
def search_url(input)
|
||||
input.gsub /(http:\/\/)(\S+)/ do
|
||||
$2
|
||||
end
|
||||
end
|
||||
def smart_quotes(input)
|
||||
require 'rubypants'
|
||||
RubyPants.new(input).to_html
|
||||
end
|
||||
def titlecase(input)
|
||||
input.titlecase
|
||||
end
|
||||
def datetime(date)
|
||||
if date.class == String
|
||||
date = Time.parse(date)
|
||||
end
|
||||
date
|
||||
end
|
||||
def ordinalize(date)
|
||||
date = datetime(date)
|
||||
"#{date.strftime('%B')} #{ordinal(date.strftime('%e').to_i)}, #{date.strftime('%Y')}"
|
||||
end
|
||||
def ordinal(number)
|
||||
if (11..13).include?(number.to_i % 100)
|
||||
"#{number}<span>th</span>"
|
||||
else
|
||||
case number.to_i % 10
|
||||
when 1; "#{number}<span>st</span>"
|
||||
when 2; "#{number}<span>nd<span>"
|
||||
when 3; "#{number}<span>rd</span>"
|
||||
else "#{number}<span>th</span>"
|
||||
end
|
||||
end
|
||||
end
|
||||
#YearlyPost = Struct.new('YearlyPost', :year, :posts)
|
||||
def yearly_posts(site)
|
||||
#site.posts.reverse.group_by { |p| p.date.strftime("%Y") }.map { |k,v| YearlyPost.new(k,v) }
|
||||
site
|
||||
end
|
||||
end
|
||||
Liquid::Template.register_filter OctopressFilters
|
||||
|
||||
133
themes/classic/_plugins/generate_sitemap.rb
Normal file
133
themes/classic/_plugins/generate_sitemap.rb
Normal file
@ -0,0 +1,133 @@
|
||||
# Jekyll sitemap page generator.
|
||||
# http://recursive-design.com/projects/jekyll-plugins/
|
||||
#
|
||||
# Version: 0.1.3 (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 a sitemap.xml page for jekyll sites, suitable for submission to
|
||||
# google etc.
|
||||
#
|
||||
# To use it, simply drop this script into the _plugins directory of your Jekyll site.
|
||||
#
|
||||
# When you compile your jekyll site, this plugin will loop through the list of pages in your
|
||||
# site, and generate an entry in sitemap.xml for each one.
|
||||
|
||||
require 'pathname'
|
||||
|
||||
module Jekyll
|
||||
|
||||
|
||||
# Monkey-patch an accessor for a page's containing folder, since
|
||||
# we need it to generate the sitemap.
|
||||
class Page
|
||||
def subfolder
|
||||
@dir
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Sub-class Jekyll::StaticFile to allow recovery from unimportant exception
|
||||
# when writing the sitemap file.
|
||||
class StaticSitemapFile < StaticFile
|
||||
def write(dest)
|
||||
super(dest) rescue ArgumentError
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Generates a sitemap.xml file containing URLs of all pages and posts.
|
||||
class SitemapGenerator < Generator
|
||||
safe true
|
||||
priority :low
|
||||
|
||||
# Domain that you are generating the sitemap for - update this to match your site.
|
||||
|
||||
# Generates the sitemap.xml file.
|
||||
#
|
||||
# +site+ is the global Site object.
|
||||
def generate(site)
|
||||
# Create the destination folder if necessary.
|
||||
site_folder = site.config['destination']
|
||||
unless File.directory?(site_folder)
|
||||
p = Pathname.new(site_folder)
|
||||
p.mkdir
|
||||
end
|
||||
|
||||
# Write the contents of sitemap.xml.
|
||||
File.open(File.join(site_folder, 'sitemap.xml'), 'w') do |f|
|
||||
f.write(generate_header())
|
||||
f.write(generate_content(site))
|
||||
f.write(generate_footer())
|
||||
f.close
|
||||
end
|
||||
|
||||
# Add a static file entry for the zip file, otherwise Site::cleanup will remove it.
|
||||
site.static_files << Jekyll::StaticSitemapFile.new(site, site.dest, '/', 'sitemap.xml')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns the XML header.
|
||||
def generate_header
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">"
|
||||
end
|
||||
|
||||
# Returns a string containing the the XML entries.
|
||||
#
|
||||
# +site+ is the global Site object.
|
||||
def generate_content(site)
|
||||
result = ''
|
||||
|
||||
base_url = site.config['url']
|
||||
|
||||
# First, try to find any stand-alone pages.
|
||||
site.pages.each{ |page|
|
||||
path = page.subfolder + '/' + page.name
|
||||
mod_date = File.mtime(site.source + path)
|
||||
|
||||
# Remove the trailing 'index.html' if there is one, and just output the folder name.
|
||||
if path=~/index.html$/
|
||||
path = path[0..-11]
|
||||
end
|
||||
|
||||
unless path =~/error/
|
||||
result += entry(base_url, path, mod_date)
|
||||
end
|
||||
}
|
||||
|
||||
# Next, find all the posts.
|
||||
posts = site.site_payload['site']['posts']
|
||||
for post in posts do
|
||||
result += entry(base_url, post.id, post.date)
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
# Returns the XML footer.
|
||||
def generate_footer
|
||||
"\n</urlset>"
|
||||
end
|
||||
|
||||
# Creates an XML entry from the given path and date.
|
||||
#
|
||||
# +path+ is the URL path to the page.
|
||||
# +date+ is the date the file was modified (in the case of regular pages), or published (for blog posts).
|
||||
def entry(base_url, path, date)
|
||||
# Force extensions to .html from markdown, textile.
|
||||
path = path.gsub(/\.(markdown|textile)$/i, '.html')
|
||||
"
|
||||
<url>
|
||||
<loc>#{base_url}#{path}</loc>
|
||||
<lastmod>#{date.strftime("%Y-%m-%d")}</lastmod>
|
||||
</url>"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
83
themes/classic/_plugins/gist_tag.rb
Normal file
83
themes/classic/_plugins/gist_tag.rb
Normal file
@ -0,0 +1,83 @@
|
||||
# Nicked from Brandon Tilly
|
||||
# Gist https://gist.github.com/803483
|
||||
# Post http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html
|
||||
#
|
||||
# Example usage: {% gist 803483 gist_tag.rb %} //embeds a gist for this plugin
|
||||
|
||||
require 'digest/md5'
|
||||
require 'net/https'
|
||||
require 'uri'
|
||||
|
||||
module Jekyll
|
||||
class GistTag < Liquid::Tag
|
||||
def initialize(tag_name, text, token)
|
||||
super
|
||||
system('mkdir -p .gist_cache')
|
||||
@text = text
|
||||
@cache = true
|
||||
@cache_folder = File.expand_path "../.gist_cache", File.dirname(__FILE__)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
return "" unless @text =~ /([\d]*) (.*)/
|
||||
|
||||
gist, file = $1.strip, $2.strip
|
||||
script_url = "https://gist.github.com/#{gist}.js?file=#{file}"
|
||||
|
||||
code = get_cached_gist(gist, file) || get_gist_from_web(gist, file)
|
||||
code = code.gsub "<", "<"
|
||||
string = "<script src='#{script_url}'></script>"
|
||||
string += "<noscript><pre><code>#{code}</code></pre></noscript>"
|
||||
return string
|
||||
end
|
||||
|
||||
def get_gist_url_for(gist, file)
|
||||
"https://gist.github.com/raw/#{gist}/#{file}"
|
||||
end
|
||||
|
||||
def cache_gist(gist, file, data)
|
||||
file = get_cache_file_for gist, file
|
||||
File.open(file, "w+") do |f|
|
||||
f.write(data)
|
||||
end
|
||||
end
|
||||
|
||||
def get_cached_gist(gist, file)
|
||||
return nil if @cache == false
|
||||
file = get_cache_file_for gist, file
|
||||
return nil unless File.exist?(file)
|
||||
return File.new(file).readlines.join
|
||||
end
|
||||
|
||||
def get_cache_file_for(gist, file)
|
||||
gist.gsub! /[^a-zA-Z0-9\-_\.]/, ''
|
||||
file.gsub! /[^a-zA-Z0-9\-_\.]/, ''
|
||||
md5 = Digest::MD5.hexdigest "#{gist}-#{file}"
|
||||
File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache"
|
||||
end
|
||||
|
||||
def get_gist_from_web(gist, file)
|
||||
gist_url = get_gist_url_for(gist, file)
|
||||
raw_uri = URI.parse(gist_url)
|
||||
https = Net::HTTP.new(raw_uri.host, raw_uri.port)
|
||||
https.use_ssl = true
|
||||
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
request = Net::HTTP::Get.new(raw_uri.request_uri)
|
||||
data = https.request(request)
|
||||
data = data.body
|
||||
cache_gist(gist, file, data) unless @cache == false
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
class GistTagNoCache < GistTag
|
||||
def initialize(tag_name, text, token)
|
||||
super
|
||||
@cache = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('gist', Jekyll::GistTag)
|
||||
Liquid::Template.register_tag('gistnocache', Jekyll::GistTagNoCache)
|
||||
|
||||
24
themes/classic/_plugins/haml.rb
Normal file
24
themes/classic/_plugins/haml.rb
Normal file
@ -0,0 +1,24 @@
|
||||
module Jekyll
|
||||
require 'haml'
|
||||
class HamlConverter < Converter
|
||||
safe true
|
||||
priority :low
|
||||
|
||||
def matches(ext)
|
||||
ext =~ /haml/i
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
begin
|
||||
engine = Haml::Engine.new(content)
|
||||
engine.render
|
||||
rescue StandardError => e
|
||||
puts "!!! HAML Error: " + e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
themes/classic/_plugins/iterator.rb
Normal file
49
themes/classic/_plugins/iterator.rb
Normal file
@ -0,0 +1,49 @@
|
||||
##
|
||||
## Author: Jose Gonzalez - https://github.com/josegonzalez
|
||||
## Source URL: https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/iterator.rb
|
||||
##
|
||||
|
||||
#module Jekyll
|
||||
#class Site
|
||||
#alias_method :orig_site_payload, :site_payload
|
||||
|
||||
## Constuct an array of hashes that will allow the user, using Liquid, to
|
||||
## iterate through the keys of _kv_hash_ and be able to iterate through the
|
||||
## elements under each key.
|
||||
##
|
||||
## Example:
|
||||
## categories = { 'Ruby' => [<Post>, <Post>] }
|
||||
## make_iterable(categories, :index => 'name', :items => 'posts')
|
||||
## Will allow the user to iterate through all categories and then iterate
|
||||
## though each post in the current category like so:
|
||||
## {% for category in site.categories %}
|
||||
## h1. {{ category.name }}
|
||||
## <ul>
|
||||
## {% for post in category.posts %}
|
||||
## <li>{{ post.title }}</li>
|
||||
## {% endfor %}
|
||||
## </ul>
|
||||
## {% endfor %}
|
||||
##
|
||||
## Returns [ {<index> => <kv_hash_key>, <items> => kv_hash[<kv_hash_key>]}, ... ]
|
||||
|
||||
#def make_iterable(kv_hash, options)
|
||||
#options = {:index => 'name', :items => 'items'}.merge(options)
|
||||
#result = []
|
||||
#kv_hash.sort.each do |key, value|
|
||||
#result << { options[:index] => key, options[:items] => value }
|
||||
#end
|
||||
#result
|
||||
#end
|
||||
|
||||
#def site_payload
|
||||
#payload = orig_site_payload
|
||||
#payload['site']['iterable'].merge!({
|
||||
#'categories' => make_iterable(self.categories, :index => 'name', :items => 'posts'),
|
||||
#'tags' => make_iterable(self.tags, :index => 'name', :items => 'posts')
|
||||
#})
|
||||
#payload
|
||||
#end
|
||||
|
||||
#end
|
||||
#end
|
||||
30
themes/classic/_plugins/pygments_cache_patch.rb
Normal file
30
themes/classic/_plugins/pygments_cache_patch.rb
Normal file
@ -0,0 +1,30 @@
|
||||
#
|
||||
# Author: Raimonds Simanovskis, http://blog.rayapps.com/
|
||||
# Source URL: https://github.com/rsim/blog.rayapps.com/blob/master/_plugins/pygments_cache_patch.rb
|
||||
#
|
||||
|
||||
require 'fileutils'
|
||||
require 'digest/md5'
|
||||
|
||||
PYGMENTS_CACHE_DIR = File.expand_path('../../_cache', __FILE__)
|
||||
FileUtils.mkdir_p(PYGMENTS_CACHE_DIR)
|
||||
|
||||
Jekyll::HighlightBlock.class_eval do
|
||||
def render_pygments(context, code)
|
||||
if defined?(PYGMENTS_CACHE_DIR)
|
||||
path = File.join(PYGMENTS_CACHE_DIR, "#{@lang}-#{Digest::MD5.hexdigest(code)}.html")
|
||||
if File.exist?(path)
|
||||
highlighted_code = File.read(path)
|
||||
else
|
||||
highlighted_code = Albino.new(code, @lang).to_s(@options)
|
||||
File.open(path, 'w') {|f| f.print(highlighted_code) }
|
||||
end
|
||||
else
|
||||
highlighted_code = Albino.new(code, @lang).to_s(@options)
|
||||
end
|
||||
output = add_code_tags(highlighted_code, @lang)
|
||||
output = context["pygments_prefix"] + output if context["pygments_prefix"]
|
||||
output = output + context["pygments_suffix"] if context["pygments_suffix"]
|
||||
output
|
||||
end
|
||||
end
|
||||
309
themes/classic/_plugins/sitemap_generator.rb
Normal file
309
themes/classic/_plugins/sitemap_generator.rb
Normal file
@ -0,0 +1,309 @@
|
||||
# Sitemap.xml Generator is a Jekyll plugin that generates a sitemap.xml file by
|
||||
# traversing all of the available posts and pages.
|
||||
#
|
||||
# How To Use:
|
||||
# 1.) Copy source file into your _plugins folder within your Jekyll project.
|
||||
# 2.) Change MY_URL to reflect your domain name.
|
||||
# 3.) Change SITEMAP_FILE_NAME if you want your sitemap to be called something
|
||||
# other than sitemap.xml.
|
||||
# 4.) Change the PAGES_INCLUDE_POSTS list to include any pages that are looping
|
||||
# through your posts (e.g. "index.html", "archive.html", etc.). This will
|
||||
# ensure that right after you make a new post, the last modified date will
|
||||
# be updated to reflect the new post.
|
||||
# 5.) Run Jekyll: jekyll --server to re-generate your site.
|
||||
# 6.) A sitemap.xml should be included in your _site folder.
|
||||
#
|
||||
# Customizations:
|
||||
# 1.) If there are any files you don't want included in the sitemap, add them
|
||||
# to the EXCLUDED_FILES list. The name should match the name of the source
|
||||
# file.
|
||||
# 2.) If you want to include the optional changefreq and priority attributes,
|
||||
# simply include custom variables in the YAML Front Matter of that file.
|
||||
# The names of these custom variables are defined below in the
|
||||
# CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME and PRIORITY_CUSTOM_VARIABLE_NAME
|
||||
# constants.
|
||||
#
|
||||
# Notes:
|
||||
# 1.) The last modified date is determined by the latest from the following:
|
||||
# system modified date of the page or post, system modified date of
|
||||
# included layout, system modified date of included layout within that
|
||||
# layout, ...
|
||||
#
|
||||
# Author: Michael Levin
|
||||
# Site: http://www.kinnetica.com
|
||||
# Distributed Under A Creative Commons License
|
||||
# - http://creativecommons.org/licenses/by/3.0/
|
||||
|
||||
require 'rexml/document'
|
||||
|
||||
module Jekyll
|
||||
|
||||
# Change MY_URL to reflect the site you are using
|
||||
MY_URL = "http://www.mysite.com"
|
||||
|
||||
# Change SITEMAP_FILE_NAME if you would like your sitemap file
|
||||
# to be called something else
|
||||
SITEMAP_FILE_NAME = "sitemap.xml"
|
||||
|
||||
# Any files to exclude from being included in the sitemap.xml
|
||||
EXCLUDED_FILES = ["atom.xml"]
|
||||
|
||||
# Any files that include posts, so that when a new post is added, the last
|
||||
# modified date of these pages should take that into account
|
||||
PAGES_INCLUDE_POSTS = ["index.html"]
|
||||
|
||||
# Custom variable names for changefreq and priority elements
|
||||
# These names are used within the YAML Front Matter of pages or posts
|
||||
# for which you want to include these properties
|
||||
CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME = "change_frequency"
|
||||
PRIORITY_CUSTOM_VARIABLE_NAME = "priority"
|
||||
|
||||
class Post
|
||||
attr_accessor :name
|
||||
|
||||
def full_path_to_source
|
||||
File.join(@base, @name)
|
||||
end
|
||||
|
||||
def location_on_server
|
||||
"#{MY_URL}#{url}"
|
||||
end
|
||||
end
|
||||
|
||||
class Page
|
||||
attr_accessor :name
|
||||
|
||||
def full_path_to_source
|
||||
File.join(@base, @dir, @name)
|
||||
end
|
||||
|
||||
def location_on_server
|
||||
location = "#{MY_URL}#{@dir}#{url}"
|
||||
location.gsub(/index.html$/, "")
|
||||
end
|
||||
end
|
||||
|
||||
class Layout
|
||||
def full_path_to_source
|
||||
File.join(@base, @name)
|
||||
end
|
||||
end
|
||||
|
||||
# Recover from strange exception when starting server without --auto
|
||||
class SitemapFile < StaticFile
|
||||
def write(dest)
|
||||
begin
|
||||
super(dest)
|
||||
rescue
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class SitemapGenerator < Generator
|
||||
|
||||
# Valid values allowed by sitemap.xml spec for change frequencies
|
||||
VALID_CHANGE_FREQUENCY_VALUES = ["always", "hourly", "daily", "weekly",
|
||||
"monthly", "yearly", "never"]
|
||||
|
||||
# Goes through pages and posts and generates sitemap.xml file
|
||||
#
|
||||
# Returns nothing
|
||||
def generate(site)
|
||||
sitemap = REXML::Document.new << REXML::XMLDecl.new("1.0", "UTF-8")
|
||||
|
||||
urlset = REXML::Element.new "urlset"
|
||||
urlset.add_attribute("xmlns",
|
||||
"http://www.sitemaps.org/schemas/sitemap/0.9")
|
||||
|
||||
@last_modified_post_date = fill_posts(site, urlset)
|
||||
fill_pages(site, urlset)
|
||||
|
||||
sitemap.add_element(urlset)
|
||||
|
||||
# File I/O: create sitemap.xml file and write out pretty-printed XML
|
||||
file = File.new(File.join(site.dest, SITEMAP_FILE_NAME), "w")
|
||||
formatter = REXML::Formatters::Pretty.new(4)
|
||||
formatter.compact = true
|
||||
formatter.write(sitemap, file)
|
||||
file.close
|
||||
|
||||
# Keep the sitemap.xml file from being cleaned by Jekyll
|
||||
site.static_files << Jekyll::SitemapFile.new(site, site.dest, "/", SITEMAP_FILE_NAME)
|
||||
end
|
||||
|
||||
# Create url elements for all the posts and find the date of the latest one
|
||||
#
|
||||
# Returns last_modified_date of latest post
|
||||
def fill_posts(site, urlset)
|
||||
last_modified_date = nil
|
||||
site.posts.each do |post|
|
||||
if !excluded?(post.name)
|
||||
url = fill_url(site, post)
|
||||
urlset.add_element(url)
|
||||
end
|
||||
|
||||
path = post.full_path_to_source
|
||||
date = File.mtime(path)
|
||||
last_modified_date = date if last_modified_date == nil or date > last_modified_date
|
||||
end
|
||||
|
||||
last_modified_date
|
||||
end
|
||||
|
||||
# Create url elements for all the normal pages and find the date of the
|
||||
# index to use with the pagination pages
|
||||
#
|
||||
# Returns last_modified_date of index page
|
||||
def fill_pages(site, urlset)
|
||||
site.pages.each do |page|
|
||||
if !excluded?(page.name)
|
||||
path = page.full_path_to_source
|
||||
if File.exists?(path)
|
||||
url = fill_url(site, page)
|
||||
urlset.add_element(url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Fill data of each URL element: location, last modified,
|
||||
# change frequency (optional), and priority.
|
||||
#
|
||||
# Returns url REXML::Element
|
||||
def fill_url(site, page_or_post)
|
||||
url = REXML::Element.new "url"
|
||||
|
||||
loc = fill_location(page_or_post)
|
||||
url.add_element(loc)
|
||||
|
||||
lastmod = fill_last_modified(site, page_or_post)
|
||||
url.add_element(lastmod) if lastmod
|
||||
|
||||
if (page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME])
|
||||
change_frequency =
|
||||
page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME].downcase
|
||||
|
||||
if (valid_change_frequency?(change_frequency))
|
||||
changefreq = REXML::Element.new "changefreq"
|
||||
changefreq.text = change_frequency
|
||||
url.add_element(changefreq)
|
||||
else
|
||||
puts "ERROR: Invalid Change Frequency In #{page_or_post.name}"
|
||||
end
|
||||
end
|
||||
|
||||
if (page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME])
|
||||
priority_value = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]
|
||||
if valid_priority?(priority_value)
|
||||
priority = REXML::Element.new "priority"
|
||||
priority.text = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]
|
||||
url.add_element(priority)
|
||||
else
|
||||
puts "ERROR: Invalid Priority In #{page_or_post.name}"
|
||||
end
|
||||
end
|
||||
|
||||
url
|
||||
end
|
||||
|
||||
# Get URL location of page or post
|
||||
#
|
||||
# Returns the location of the page or post
|
||||
def fill_location(page_or_post)
|
||||
loc = REXML::Element.new "loc"
|
||||
loc.text = page_or_post.location_on_server
|
||||
|
||||
loc
|
||||
end
|
||||
|
||||
# Fill lastmod XML element with the last modified date for the page or post.
|
||||
#
|
||||
# Returns lastmod REXML::Element or nil
|
||||
def fill_last_modified(site, page_or_post)
|
||||
path = page_or_post.full_path_to_source
|
||||
|
||||
lastmod = REXML::Element.new "lastmod"
|
||||
date = File.mtime(path)
|
||||
latest_date = find_latest_date(date, site, page_or_post)
|
||||
|
||||
if @last_modified_post_date == nil
|
||||
# This is a post
|
||||
lastmod.text = latest_date.iso8601
|
||||
else
|
||||
# This is a page
|
||||
if posts_included?(page_or_post.name)
|
||||
# We want to take into account the last post date
|
||||
final_date = greater_date(latest_date, @last_modified_post_date)
|
||||
lastmod.text = final_date.iso8601
|
||||
else
|
||||
lastmod.text = latest_date.iso8601
|
||||
end
|
||||
end
|
||||
lastmod
|
||||
end
|
||||
|
||||
# Go through the page/post and any implemented layouts and get the latest
|
||||
# modified date
|
||||
#
|
||||
# Returns formatted output of latest date of page/post and any used layouts
|
||||
def find_latest_date(latest_date, site, page_or_post)
|
||||
layouts = site.layouts
|
||||
layout = layouts[page_or_post.data["layout"]]
|
||||
while layout
|
||||
path = layout.full_path_to_source
|
||||
date = File.mtime(path)
|
||||
|
||||
latest_date = date if (date > latest_date)
|
||||
|
||||
layout = layouts[layout.data["layout"]]
|
||||
end
|
||||
|
||||
latest_date
|
||||
end
|
||||
|
||||
# Which of the two dates is later
|
||||
#
|
||||
# Returns latest of two dates
|
||||
def greater_date(date1, date2)
|
||||
if (date1 >= date2)
|
||||
date1
|
||||
else
|
||||
date2
|
||||
end
|
||||
end
|
||||
|
||||
# Is the page or post listed as something we want to exclude?
|
||||
#
|
||||
# Returns boolean
|
||||
def excluded?(name)
|
||||
EXCLUDED_FILES.include? name
|
||||
end
|
||||
|
||||
def posts_included?(name)
|
||||
PAGES_INCLUDE_POSTS.include? name
|
||||
end
|
||||
|
||||
# Is the change frequency value provided valid according to the spec
|
||||
#
|
||||
# Returns boolean
|
||||
def valid_change_frequency?(change_frequency)
|
||||
VALID_CHANGE_FREQUENCY_VALUES.include? change_frequency
|
||||
end
|
||||
|
||||
# Is the priority value provided valid according to the spec
|
||||
#
|
||||
# Returns boolean
|
||||
def valid_priority?(priority)
|
||||
begin
|
||||
priority_val = Float(priority)
|
||||
return true if priority_val >= 0.0 and priority_val <= 1.0
|
||||
rescue ArgumentError
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
36
themes/classic/_plugins/titlecase.rb
Normal file
36
themes/classic/_plugins/titlecase.rb
Normal file
@ -0,0 +1,36 @@
|
||||
class String
|
||||
def titlecase
|
||||
small_words = %w(a an and as at but by en for if in of on or the to v v. via vs vs.)
|
||||
|
||||
x = split(" ").map do |word|
|
||||
# note: word could contain non-word characters!
|
||||
# downcase all small_words, capitalize the rest
|
||||
small_words.include?(word.gsub(/\W/, "").downcase) ? word.downcase! : word.smart_capitalize!
|
||||
word
|
||||
end
|
||||
# capitalize first and last words
|
||||
x.first.to_s.smart_capitalize!
|
||||
x.last.to_s.smart_capitalize!
|
||||
# small words after colons are capitalized
|
||||
x.join(" ").gsub(/:\s?(\W*#{small_words.join("|")}\W*)\s/) { ": #{$1.smart_capitalize} " }
|
||||
end
|
||||
|
||||
def titlecase!
|
||||
replace(titlecase)
|
||||
end
|
||||
|
||||
def smart_capitalize
|
||||
# ignore any leading crazy characters and capitalize the first real character
|
||||
if self =~ /^['"\(\[']*([a-z])/
|
||||
i = index($1)
|
||||
x = self[i,self.length]
|
||||
# word with capitals and periods mid-word are left alone
|
||||
self[i,1] = self[i,1].upcase unless x =~ /[A-Z]/ or x =~ /\.\w+/
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def smart_capitalize!
|
||||
replace(smart_capitalize)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user