Simple Sitemap.xml in Rails 3.1

 Feb 4, 2013

There are all sorts of ways you could set up a sitemap for your rails 3.1 application.

If you want to add urls dynamically, from blog posts for example, here is one way to do it

First off at a route to your config/routes.rb

match '/sitemap' => 'sitemap#index'

Then generate a new controller with an index action

$ rails g controller sitemap index

Once this is done, you can delete most of the files that are auto generated with the controller as we won’t be styling it or adding scripts.

  • assets/stylesheets/sitemap.css.scss
  • assets/javascripts/sitemap.js.coffee
  • helpers/sitemap_helper.rb

Next up we need to modify the index action to generate our data for the sitemap view

class SitemapController < ApplicationController
  layout nil

  def index 
    last_post = Post.last
    if stale?(:etag => last_post, :last_modified => last_post.updated_at.utc)  
      respond_to do |format|
        format.xml do
          @posts = Post.all
        end
      end
    end
  end
end

The stale? method will respond with a HTTP 304 Not Modified if there have been no new posts

Lastly the view that was created will be for the HTML response, so you need to create a views/sitemap/index.xml.erb

<% base_url = "http://#{request.host_with_port}" %>
<?xml version="1.0" encoding="utf-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <% @posts.each do |post| %>
    <url>
      <loc><%= base_url + post_path(post) %></loc>
      <lastmod><%= post.updated_at.iso8601 %></lastmod>
    </url>
  <% end %>
</urlset>

Footnotes