Wer sich bereits eingehender mit Ruby on Rails beschäftigt hat, der weiß dass dieses beliebte Framework einem viele Aufgaben von Haus aus abnimmt und diese vereinfacht.
In den Tagen des Social Webs gehört es unter anderem zu den häufigen Aufgaben eines Entwicklers, XML Dokumente zu generieren, oder APIs auf Basis von XML bereitzustellen. News wollen in Form von RSS oder Atom abonniert werden, Inhalte aus anderen Webangeboten über XML in die eigenen Seiten integriert werden.
XML ist also ziemlich wichtig und daher sollte das Erstellen und die Verarbeitung von XML mit einem Framework wie Ruby on Rails auch so einfach und unkompliziert wie möglich erfolgen.
Was ist Google Sitemaps?
Wie dies funktioniert und welche Schritte dafür notwendig sind, werde ich am Beispiel einer Google Sitemap für ein Blog zeigen. Google stellt mit Google Sitemaps eine Methode zur Verfügung, um neue Inhalte aus dynamischen Webseiten noch schneller in den Google Suchindex aufnehmen zu lassen. Dazu können Webseiten eine sitemap.xml Datei zur Verfügung stellen, welche in Form von XML Daten wie URL, Erstell- bzw. Updatedatum und eine Indizierungspriorität zu allen verfügbaren Seiten - in unserem Fall sind dies die Blogeinträge - enthalten kann.
Rails Generator hilft uns
Bei großen dynamischen Seiten ist es natürlich aufwendig, diese XML Datei immer von Hand zu pflegen, darum wollen wir diese mit den Mitteln von Ruby on Rails automatisch generieren lassen.
Überlegen wir doch erstmal, was wir alles für die geforderte Aufgabe benötigen. Wir brauchen einen Sitemap Controller mit einer index Action, welche wir aufrufen können und die dann schließlich das XML generiert. Also sollten wir zuerst diesen neuen Controller generieren lassen. Dies ist in Ruby on Rails mehr als einfach:
ruby script/generate controller Sitemap index
Dieser Komandozeilenaufruf nimmt uns diese Aufgabe ab. Der Rails Generator legt daraufhin mehrere Dateien an. Unter anderem den Controller sitemap_controller.rb mit der Action index und den View index.html.erb.
exists app/controllers/ exists app/helpers/ create app/views/sitemap exists test/functional/ create app/controllers/sitemap_controller.rb create test/functional/sitemap_controller_test.rb create app/helpers/sitemap_helper.rb create app/views/sitemap/index.html.erb
Der Controller
Im nächsten Schritt holen wir uns in der bereits für uns angelegten index Action eine Liste mit allen vorhandenen Blogeinträgen und sagen Rails, dass das Ergebnis als XML gerendert werden soll.
class SitemapController < ApplicationController
def index
@articles = BlogArticle.find(:all, :order => 'created_on DESC, updated_on DESC')
respond_to do |format|
format.xml { }
end
end
end
Wie man sehen kann, sortieren wir die gefundenen Blogeinträge absteigend nach Erstellungs- und Bearbeitungsdatum. So ist sichergestellt, dass die aktuellsten Einträge in der XML Datei später immer am Anfang stehen.
Mit Rails XMLBuilder ist XML so einfach wie noch nie
Wie im ersten Schritt zu sehen, hat Rails für uns mit der index.hmtl.erb auch schon die Viewdatei für die index Action erstellt. Da wir jedoch kein HTML sondern XML ausgeben wollen, benennen wir diese Datei in index.xml.builder um.
Diese Umbenennung hat zwei Effekte. Rails wird auf diese Datei automatisch zurückgreifen, wenn XML gerendert werden soll und die Endung .builder teilt Rails mit, dass der Inhalt dieser Datei Anweisungen für den Rails eigenen XML Builder enthält. Mit diesem Builder lassen sich schnell komplexe XML Dateien erstellen, wie wir am folgenden Beispiel sehen werden.
xml.instruct!
xml.urlset "xmlns" => "http://www.google.com/schemas/sitemap/0.84" do
xml.url do
xml.loc "http://www.name-der-seite.de/"
xml.lastmod w3c_date(Time.now)
xml.changefreq "always"
end
@articles.each do |article|
xml.url do
xml.loc url_for(:only_path => false, :controller => 'blog', :action => 'show', :id => article)
xml.lastmod w3c_date(article.created_on)
xml.changefreq "weekly"
xml.priority 0.8
end
end
end
Dieser Code ist so ziemlich selbsterklärend. Es wird über verschiedene xml Anweisungen die Struktur der sitemap.xml erzeugt und über alle BlogArticles iteriert.
Eine Hilfe für das Datumsformat
Zur Ausgabe des Datums im richtigen Format haben wir die Methode w3c_date() im sitemap_helper.rb definiert.
module SitemapHelper
def w3c_date(date)
date.utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
end
end
Fast fertig
Damit wir diese Action nun auch über die URL http://www.name-der-seite.de/sitemap.xml aufrufen können, werden wir in der Datei routes.rb noch ein entsprechendes Mapping anlegen.
map.connect "sitemap.xml", :controller => "sitemap", :action => "index"
Nun steht dem Aufruf durch Google und der anschließenden erfolgreichen Indizierung unserer gesamten Blogbeiträge nichts mehr im Weg.
Abschließend kann man sagen, dass XML mit Ruby on Rails wirklich nicht schwer ist. Wenn man den gesamten Aufwand betrachtet, so konnten wir die geforderte Funktionalität in 5 bis 10 Minuten umsetzen. Wenn das nicht effektiv ist, was denn dann? :o)
Statt eine w3c_date Methode zu schreiben, kann man auch einfach #xmlschema benutzen:
>> Time.now.xmlschema
=> „2009-01-23T23:20:18+01:00“
Und wer nicht die URL der Seite direkt in den Builder schreiben will (z.B. weil die Anwendung auf mehreren Domains läuft), der kann stattdessen root_url einsetzen, so dass immer automatisch die richtige Adresse in der sitemap steht.