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
$ 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
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