Generating valid Atom feeds from Rails 2.0.2
Update to create an auto discover link to your feed use the formatted_resources_url helper:
# app/views/polls/index.html.erb <% content_for :header do %> <%= tag(:link, :rel => "alternate", :type => "application/atom+xml", :href => formatted_polls_url(:format => :atom)) %> <% end %> # app/views/layouts/application.html.erb header block <%= yield(:header) %>
Update: does anyone know if Google Reader takes a while to process new feeds and render them correctly?
I just put up a feed that was validated it took Google Reader quite a long time to finally figure out how to display its name correctly.
I’ve built a few RSS feeds using builder and just came across this for building Atom feeds.
The Rails team seem to have picked Atom over RSS as their feed format of choice, there’s no mention of RSS in the API documentation.
So… go with the flow right? Why bother with RSS?
Now, sadly Rails 2.0.2 doesn’t generate valid feeds but there’s a patch on edge that will fix that.
From Rails changeset 8529 download a new version of atom_feed_helper.rb (link or look for the zip at the bottom of the changeset page) and drop it into your config/initializers directory to monkey patch Rails. Restart your server.
WARNING: learner driver steering, this is the first time I’ve patched Rails in this way but it seems to not break anything with some very minor testing.
Assuming that we’re dealing with resourceful routing:
# app/views/polls_controllers.rb
def index
@polls = Poll.find(:all)
respond_to do |format|
format.html # index.html.erb
format.atom # index.atom.builder
format.xml { render :xml => @polls }
end
end
# app/views/polls/index.atom.builder
atom_feed(:schema_date => "2008-04-22") do |feed|
feed.title("Pollthing polls")
feed.updated((@polls.first.created_at))
for poll in @polls
feed.entry(poll) do |entry|
entry.title(poll.title)
entry.content(poll.feed_description, :type => 'html')
entry.author do |author|
author.name("Pollthing")
end
end
end
end
Job done.
The big difference here between implementing Atom and RSS is that all the links and date stamps are created for you. You can concentrate on things that matter to the application: title, author and description.
Compare with some scavenged builder code that does RSS…
xml.instruct! :xml, :version=>"1.0"
xml.rss(:version=>"2.0"){
xml.channel{
xml.title(@blog_posts.blog.title)
xml.link("http://localhost:3000/blog_posts.rss")
xml.description(@blog_posts.blog.description)
xml.language('en-us')
for post in @blog_posts
xml.item do
xml.title(post.title)
xml.category()
xml.description(post.body)
xml.pubDate(post.created_at.strftime("%a, %d %b %Y %H:%M:%S %z"))
xml.link("http://localhost:3000/blog_posts/" + post.id.to_s)
xml.guid("http://localhost:3000/blog_posts/" + post.id.to_s)
end
end
}
}