Life In The Stack Trace...

TODO: <Insert clever marketing phrase here>

Defining Rails 3.x Sitemaps Using DuckMap

Duck Map gem is designed as a Rails Engine. Many things are done for you, however, here is a list of a few:

  • A default sitemap is configured for you containing all of the routes defined via config/routes.rb
  • The default sitemap name is: sitemap.
  • You can view the default sitemap at: http://localhost:3000/sitemap.xml
  • You can override the default sitemap by using a sitemap block.
  • If no routes are defined in config/routes.rb, sitemap will produce an empty sitemap.

Consider the following example config/routes.rb

# the following example will produce a default sitemap and requires zero configuration.
MyApp::Application.routes.draw do

  resources :trucks
  root :to => "home#index"

end

contents of http://localhost:3000/sitemap.xml will look similar to the following:

<url>
  <loc>http://localhost:3000/trucks.html</loc>
  <lastmod>2011-11-03T06:44:25+00:00</lastmod>
  <changefreq>monthly</changefreq>
  <priority>0.5</priority>
</url>
<url>
  <loc>http://localhost:3000/</loc>
  <lastmod>2011-11-03T06:44:25+00:00</lastmod>
  <changefreq>monthly</changefreq>
  <priority>0.5</priority>
</url>

Download the support file, expand it and have a look at default.com app.

sudo bundle install
rake db:migrate
rails s

Add a few trucks to the database and have a look at the sitemap. You will notice that the sitemap will reflect the records you add to the database.

Using Sitemap Block Statements

You can control the contents of your sitemap using block statements. Sitemaps are defined in config/routes.rb by enclosing named routes within a sitemap block. The default sitemap is the equivalent of enclosing the entire contents of config/routes.rb in a sitemap block. The following example redefines the default sitemap by wrapping a few routes in a sitemap block. Notice that bikes is excluded from the default sitemap.

MyApp::Application.routes.draw do

  # notice that bikes is not included in the default sitemap.
  resources :bikes

  # here we are wrapping a couple of routes for inclusion in the default sitemap.
  sitemap do
    resources :cars
    resources :trucks
    root :to => 'home#index'
  end

end

contents of sitemap.xml will look similar to the following:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://localhost:3000/cars.html</loc>
    <lastmod>2011-11-03T07:35:00+00:00</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>http://localhost:3000/trucks.html</loc>
    <lastmod>2011-11-03T07:35:00+00:00</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>http://localhost:3000/</loc>
    <lastmod>2011-11-03T07:35:00+00:00</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

You see it in action in the app: blocks.com

Sitemap Block Rules

You can include as many sitemap blocks as you desire. All sitemap blocks can point to the same sitemap name, multiple names, or any combination. The following two blocks are equivalent and produce a single sitemap.

MyApp::Application.routes.draw do

  # this is adding routes to the default sitemap
  sitemap do
    resources :cars
    root :to => 'home#index'
  end

  # this is adding routes to the default sitemap as well
  sitemap :sitemap do
    resources :bikes
    resources :trucks
  end

end

Now, the default sitemap would contain cars, trucks, and the root url by simply merging all of the definitions into one. It doesn't matter how many times you define a sitemap block. It will ALWAYS merges all routes into one sitemap definition.

The simple rule for using sitemap blocks is:

  • If a sitemap block has been defined, include everything within the block.
  • If no sitemap blocks have been defined, include everything in config/routes.rb.

In fact, the default sitemap is defined without a block and includes all routes in config/routes.rb. However, if you redefine the default sitemap using a block only those routes will be included.

You see it in action in the app: multiblocks.com

Addendum

I thought of this while writing the namespace article and thought it might be a good idea to show all of the different possible combinations that will produce the same result and you can see it in action in the app: combo.com

# default sitemap is created for you via config/routes.rb found in the duck_map gem
ComboCom::Application.routes.draw do

  root to: 'home#index'
  resources :bikes
  resources :cars
  resources :trucks

end

# This is exactly what the duck_map is doing for you via config/routes.rb found in the duck_map gem
ComboCom::Application.routes.draw do

  sitemap

  root to: 'home#index'
  resources :bikes
  resources :cars
  resources :trucks

end

# redefining the default sitemap using a block with no name.
ComboCom::Application.routes.draw do

  sitemap do

    root to: 'home#index'
    resources :bikes
    resources :cars
    resources :trucks

  end

end

ComboCom::Application.routes.draw do

  # redefining the default sitemap without using a block, but, passing in the default name.
  sitemap :sitemap

  root to: 'home#index'
  resources :bikes
  resources :cars
  resources :trucks

end

ComboCom::Application.routes.draw do

  # redefining the default sitemap using a block and passing in the default name.
  sitemap :sitemap do

    root to: 'home#index'
    resources :bikes
    resources :cars
    resources :trucks

  end

end