Rails で Atom / RSS フィードを生成する Builder テンプレート
Web サイトの更新を通知する Atom / RSS フィードは、現在の Web サイトになくてはならないもののひとつです。当然、 WebOS Goodies でも配信しているわけですが、独自 CMS に移行した際に、それらのフィードも自分で生成しなくてはならなくなりました。そこで、わりと汎用的に使える Builder テンプレートを作ってみたので、本日はそれをご紹介しようと思います。
一応、 Feed Validator で Valid の評価が貰えるようになっていますので、よろしければご利用ください。
ソースコード
まずはソースコードです。適当にコピペして使ってください。
こちらが Atom 用のテンプレート。
atom_feed(:language => 'ja-JP', :root_url => @site_url, :url => @atom_url, :id => @site_url) do |feed| feed.title @site_title feed.subtitle @site_description feed.updated Time.now feed.author{|author| author.name(@author) } @entries.each do |entry| feed.entry(entry, :url => entry.url, :id => entry.url, :published => entry.publish_date, :updated => entry.updated_at) do |item| item.title(entry.title) item.content(entry.content, :type => 'html') item.author{|author| author.name(@author) } end end end
そしてこちらが RSS 2.0 。
xml.instruct! xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/", "xmlns:atom" => "http://www.w3.org/2005/Atom") do xml.channel do xml.title @site_title xml.link @site_url xml.pubDate Time.now.rfc822 xml.description @site_description xml.atom :link, "href" => @rss_url, "rel" => "self", "type" => "application/rss+xml" @entries.each do |entry| xml.item do xml.title entry.title xml.link entry.url xml.guid entry.url xml.description entry.content xml.pubDate entry.created_at.to_formatted_s(:rfc822) xml.dc :creator, @author end end end end
使い方
基本的には、必要なテンプレートパラメータを設定して上記のテンプレートをレンダリングすれば、 Atom / RSS フィードが生成できます。必要なテンプレートパラメータと設定内容は以下のとおりです。
変数名 | 内容 |
---|---|
@site_title | サイトタイトル |
@site_description | サイトの説明、副題など |
@site_url | サイトの URL |
@atom_url | Atom フィードの URL |
@rss_url | RSS フィードの URL |
@author | サイト管理者の名前 |
@entries | エントリデータの配列 |
@entries は各エントリ(ブログで言えばそれぞれの記事)の配列で、通常は ActiveRecord オブジェクトになるでしょう。必要なフィールドは以下のとおり。 created_at, updated_at は DateTime 型でなければなりません。
メンバ名 | 内容 |
---|---|
title | エントリーのタイトル |
url | エントリーの URL |
content | エントリーの内容(HTML 形式) |
created_at | 公開日時 |
updated_at | 更新日時 |
URL なんかは直接フィールドに入れるもんでもないかもしれませんが、その場合は適当にテンプレートを修正してください(^^;
ちなみに、フィードをレンダリングするアクションはそれぞれ個別に用意してもいいのですが、 respond_to を利用して切り替えることもできます。例えば、 Atom / RSS のテンプレートをそれぞれ "index.atom.builder", "index.rss.builder" というファイル名で保存しておき、サイトのトップページのアクションを以下のようにすれば OK です。
def index # 必要なテンプレートパラメータを設定 respond_to do |type| type.html type.rss type.atom end end
こうしておけば、 "/index" でアクセスされた場合にはリクエストヘッダの Accept-Type によって適切なテンプレートが選択され、 "/index.atom" なら Atom フィードが、 "/index.rss" なら RSS フィードが選択されます。こちらのほうが、より Rails らしい方法ですね。
おまけ : 日本語が文字参照に変換されるのを防ぐ
上記の方法でフィードを生成すると、ひとつ困った問題にぶちあたります。なぜか日本語がすべて文字参照に変換されてしまうのです。たしかに、このままでも動作に支障はないのですが、フィードのサイズが無駄に膨れ上がって嫌な感じです。
どうやらこの変換は Rails で拡張される String#to_xs というメソッドがやっているようなので、 environment.rb の最後で以下のように上書きすることで回避することができました。
class String def to_xs ERB::Util.h(unpack('U*').pack('U*')).gsub("'", ''') # ASCII, UTF-8 rescue unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252 end end
これにより、フィード以外でも Rails が生成するすべての XML で文字参照への変換が抑制されるはずです。かなり根っこの部分の変更なので影響範囲が心配ですが、軽く検索した限り XML の生成にしか使われていないので、まあ大丈夫でしょう。
以上、本日は Rails で Atom / RSS フィードを生成するテンプレートをご紹介しました。フィードは更新情報の配信以外にも、データのエクスポートやマッシュアップなどで幅広く利用されています。生成方法をおさえておけば必ず役に立つでしょう。ぜひご活用ください!
詳しくはこちらの記事をどうぞ!
この記事にコメントする