AtomPubっぽいものを出力する方法です。

  • http://localhost:3000/example/index HTML
  • http://localhost:3000/example/index.rss RSS2.0
  • http://localhost:3000/example/index.atom Atom

という形で定義します。

Rails2.0の場合は、フォーマットによって出力を簡単に変更できますので、それを使います。

    respond_to do |format|
      format.html
      format.atom {
        render(:layout => false)
      }
      format.rss {
        render(:layout => false, :action => "index.rxml")
      }
    end

これで、Atomの場合は/views/example/index.atom.builderが、RSSの場合は/views/example/index.rxmlが読み込まれます。

Atomのテンプレートは以下のようになります。

atom_feed do |feed|
  feed.title("#{@title} » Example Feed")
  feed.updated(@memos.first.created_at)

  @memos.each do |m|
    feed.entry(m, :url => create_link(m)) do |entry|
      entry.title(m.title)
      entry.content(trans(m), :type => "html")
      entry.author do |a|
        a.name(@user.name)
      end
    end
  end
end

これはベースのようなものです。@memosというリストごとにフィードのエントリーを定義して、タイトルやcontentを作成しています。次にRSS側も同様に処理できます。


xml.instruct! :x ml, :version => "1.0", :encoding => "UTF-8"
xml.rss('version' => '2.0', 'xmlns:atom' => 'http://www.w3.org/2005/Atom', 'xmlns:openSearch' => 'http://a9.com/-/spec/opensearchrss/1.0/') do
  xml.channel do
    xml.title @title
    url = url_for(:controller => :memo, :action => :index, :id => @user.name, :o nly_path => false)
    xml.link url
    xml.tag!("atom:id", url)
    xml.description(@title)
    xml.language "en-us"
    xml.ttl "40"
    xml.pubDate(Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z"))
    xml.managingEditor(@user.name)
    xml.generator("Jot a Memo")
    xml.tag!("openSearch:totalResults", @memos.paginate.total_entries)
    xml.tag!("openSearch:startIndex", @startIndex)
    xml.tag!("openSearch:itemsPerPage", @perpage)
    xml.guid(url, "isPermaLink" => 'false')
    xml.tag!("atom:updated", Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z"))
    @memos.each do |m|
      xml.item do
        xml.title(m.title)
        xml.tag!('atom:id', create_link(m))
        xml.guid(create_link(m), "isPermaLink" => 'false')
        xml.pubDate(m.created_at)
        xml.tag!("atom:updated", m.updated_at)
        xml.tag!("atom:summary", trans(m))
        xml.link(create_link(m))
        xml.description(trans(m))
        xml.guid(create_link(m))
        xml.author(m.user.name)
      end
    end
  end
end

やたらと長いのですが、あまり気にしないでください。大事なのは、xml.tag!を使うと、<atom:id>…</atom:id>のような形式が定義できるということと、xml.guid(aa, bb)のように二つ目の引数を定義すると、それがattributesになるということです。

後は<rss>の中に拡張書式を定義する場合があると思いますが、それもHashで指定可能です。

このように定義しておくと、次に以下のようなURLを考えた場合も容易に対応できます。

  • http://localhost:3000/example/view/id HTML
  • http://localhost:3000/example/view/id.rss RSS2.0
  • http://localhost:3000/example/view/id.atom Atom

でidで指定されたデータの詳細表示を行う場合です。この場合は以下のように対応します。


    @memos = [@memo]
    respond_to do |format|
      format.html
      format.atom {
        render(:layout => false, :action => "index.atom.builder")
      }
      format.rss {
        render(:layout => false, :action => "index.rxml")
      }
    end

@memoという1件のデータを@memosに配列で入れた以外は、indexと同じ処理になります。実際、フィードで1件を表示する場合も複数件表示する場合も処理は変わらないので、これで対応できます。もちろん、HTMLの場合は異なると思いますので、view.rhtmlは内容が異なるかと思います。

とは言ってもこれではGETだけの対応なので、これからPOST/PUT/DELETEの実装を完了してはじめてAtomPubへの対応が完了したと言えるのですが。

Leave a Reply

MOONGIFTネットワーク。こちらもぜひご覧ください。
MOONGIFT

Warning: array_slice() [function.array-slice]: The first argument should be an array in /virtual/producing/public_html/producing-web.com/wp-content/themes/network.php on line 15
  • No items
Open Service
Rails 2.0
Resident on Net
iPhone最適化
リーンソフトウェア
MarketPedia
Producing Web
Cool Coding