_plugins/generate_sitemap.rb
e4c2d579
 # 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