133 lines
3.6 KiB
Ruby
133 lines
3.6 KiB
Ruby
|
# 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.
|
||
|
BASE_URL = 'http://recursive-design.com'
|
||
|
|
||
|
# 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 = ''
|
||
|
|
||
|
# 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(path, mod_date)
|
||
|
end
|
||
|
}
|
||
|
|
||
|
# Next, find all the posts.
|
||
|
posts = site.site_payload['site']['posts']
|
||
|
for post in posts do
|
||
|
result += entry(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(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
|
||
|
|
||
|
|