Skip to content

Instantly share code, notes, and snippets.

@nruth
Last active December 12, 2015 03:19
Show Gist options
  • Save nruth/4706364 to your computer and use it in GitHub Desktop.
Save nruth/4706364 to your computer and use it in GitHub Desktop.
basic rails sitemap generator
get '/sitemap', :to => 'sitemap#sitemap', :as => 'sitemap'
# -*- encoding : utf-8 -*-
class Sitemap
def self.static_view_templates
require 'fileutils'
template_paths = []
FileUtils.cd Rails.root.join 'app', 'views', 'static_pages' do
erb_html_files = File.join "**", "*.html.erb"
template_paths = Dir.glob(erb_html_files)
end
remove_html_erb!(template_paths)
template_paths -= ['home']
template_paths += ['', 'members/join']
template_paths
end
private
def self.remove_html_erb!(template_paths)
template_paths.each {|p| p.sub!(/\.html\.erb/, '')}
end
end
# -*- encoding : utf-8 -*-
class SitemapController < ApplicationController
respond_to :xml
def sitemap
response.headers['Cache-Control'] = "public, max-age=#{1.week}"
@page_paths = Sitemap.static_view_templates
end
end
# -*- encoding : utf-8 -*-
require 'spec_helper'
describe SitemapController do
describe "GET sitemap(.xml)" do
subject {get :sitemap, :format => 'xml'}
describe "static pages" do
# create some test templates
around(:each) do |example|
paths = [
Rails.root.join('app', 'views', 'static_pages', 'testpages-50-top-ukcat-tips', '01-what-is-ukcat-and-is-it-fair.html.erb'),
Rails.root.join('app', 'views', 'static_pages', 'testpages-privacy.html.erb')
]
paths.each {|path| `mkdir -p #{File.dirname(path)} && touch #{path}` }
example.run
paths.each {|path| `rm #{path}; rmdir #{File.dirname(path)}` }
end
it "should assign the static page paths list to @page_paths" do
# check some of your static pages here, if any
subject
assigns[:page_paths].should include('testpages-privacy')
assigns[:page_paths].should include('testpages-50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair')
end
end
it "should not include home, but should include the root path" do
# you may or may not need this test, depends on your static page controller or cms (if you have one)
subject
assigns[:page_paths].should include('')
assigns[:page_paths].should_not include('home')
assigns[:page_paths].should_not include('/home')
assigns[:page_paths].should_not include('/home/')
end
it "should include the member signup page" do
# business critical, or check for all your public facing pages being included; ours are mostly paywalled
subject
assigns[:page_paths].should include('members/join')
end
it {should render_template('sitemap/sitemap')}
it "should respond with xml" do
subject
response.content_type.should == 'application/xml'
response.charset.should == 'utf-8'
end
end
end
# -*- encoding : utf-8 -*-
require 'spec_helper'
describe "/sitemap" do
# Feature: Sitemap
# In order to get siterank
# As a site owner
# I want a sitemap generated for our static pages
# create some test templates
around(:each) do |example|
paths = [
Rails.root.join('app', 'views', 'static_pages', 'testpages-50-top-ukcat-tips', '01-what-is-ukcat-and-is-it-fair.html.erb'),
Rails.root.join('app', 'views', 'static_pages', 'testpages-privacy.html.erb')
]
paths.each {|path| `mkdir -p #{File.dirname(path)} && touch #{path}` }
example.run
paths.each {|path| `rm #{path}; rmdir #{File.dirname(path)}` }
end
specify "the sitemap is served correctly and includes /, home, a level 1 and a nested page" do
visit '/sitemap.xml'
response_content_type_should_be "application/xml; charset=utf-8"
page_source_should_match %Q{<?xml version="1.0" encoding="UTF-8"?>}
within 'urlset[xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"]' do
check_link_present_with_weekly_changefreq '/'
check_link_present_with_weekly_changefreq '/members/join'
check_link_present_with_weekly_changefreq '/testpages-privacy'
check_link_present_with_weekly_changefreq '/testpages-50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair'
check_all_static_templates_linked
end
response_body_should_satisfy_xml_schema "http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
end
def check_link_present_with_weekly_changefreq(path)
page.should have_xpath("//url/loc[.='http://www.example.com#{path}']/../changefreq[.='weekly']")
end
def check_all_static_templates_linked
require 'fileutils'
template_paths = []
FileUtils.cd Rails.root.join 'app', 'views', 'static_pages' do
erb_html_files = File.join "**", "*.html.erb"
template_paths = Dir.glob(erb_html_files)
end
template_paths = template_paths.map {|p| p.sub(/\.html\.erb/, '')}
template_paths = template_paths - ['home']
template_paths.each do |path|
check_link_present_with_weekly_changefreq('/' + path)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment