If you don’t know what is a sitemap, I strongly encourage you to fill this gap in knowledge first and then get back to reading.
It seems to be clear that manual updating a sitemap can turn into a horror. Hopefully we can make the Rails do the job for us.
So, what components are we going to need to build a dynamic sitemap? Well, we are going to need a separate action (or even controller), an XML view and model methods to provide us with URL data. Let’s start from creating the Sitemap
controller and its index
action:
$ script/generate controller Sitemap index
Above code will create the app/views/sitemap/index.html.erb
file, but we need to change its extension to rxml
. The reason is that we need an XML view, not an HTML view as usual. Let’s change the extension now:
$ mv index.html.erb index.rxml
To instruct Rails to send appropriate content type headers, we need to set the headers
option inside the controller. We also have to disable layout rendering:
class SitemapController < ApplicationController
def index
@urls = ['http://lukaszwrobel.pl/', 'http://lukaszwrobel.pl/about-me']
headers['Content-Type'] = 'application/xml'
render :layout => false
end
end
The next thing we are going to need is an adequate XML view, located in the app/views/sitemap/index.rxml
file. On the assumption that the @urls
property contains list of all URLs we want to show in the sitemap, our XML view looks like this:
xml.instruct! :xml, :version => '1.0'
xml.tag! 'urlset', 'xmlns' => "http://www.sitemaps.org/schemas/sitemap/0.9" do
@urls.each do |url|
xml.tag! 'url' do
xml.tag! 'loc', url
end
end
end
When we display the OUR_SITE_URL/sitemap
page, we should see properly generated XML sitemap file:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://lukaszwrobel.pl/</loc>
</url>
<url>
<loc>http://lukaszwrobel.pl/about-me</loc>
</url>
</urlset>
But the truth is that we didn’t achieve anything interesting; we still have to manually input the URL list.
The next part is application-specific. If we maintain a list of products and we want to put the URL to every product page in our sitemap, we have to get all product ids, names etc. using the find()
method and build all URLs. The url_for()
method could be turned into good use here. Automatically generated URLs can than be merged with the @urls
property inside the Sitemap
controller.
Last but not least, for some reason we may want to pretend that the sitemap is located inside a file, not a controller’s action. To achieve this effect, we need to potter with the config/routes.rb
file a little. We should add the following line:
map.sitemap 'sitemap.xml', :controller => 'sitemap'
Voila! The sitemap is now available at the OUR_SITE_URL/sitemap.xml
address.