JSON Feed

ADT疑惑の人bloxsomのJSON Feedを出力するフレーバのプロトタイプを作って遊んでたので、真似してwiki.rails2u.comも同じフォーマットで出力するようにrailsで実装してみた。
http://wiki.rails2u.com/index.json
んで利用方法はscriptタグで読み込むとjsonfeeds[フィードのURL]にデータが格納されてるのでそれを使ってアレコレ。deliciousに倣ってクエリーにcount(15〜100)とraw(bool,純粋なJSONのみで返すかどうか)を渡せる。

<script type="text/javascript" src="http://wiki.rails2u.com/index.json"></script>
<script>
alert(jsonfeeds['http://wiki.rails2u.com/index.json'].title);
</script>

な感じ。
rails側の実装は RSSフィードを作る :: wiki.rails2u.com とほとんど同じ感じで。Rubyにはruby-jsonってライブラリがあって、object.to_jsonで簡単にjsonに変換できるから楽。致命的なバグがある*1けど。

  def jsonfeeds
    require 'json/objects'
    count = @params[:count]
    raw = @params[:raw]

    if count.nil?
      count = 15
    else
      count = count.to_i
      count = 15 if count < 15
      count = 100 if count > 100
    end

    jsonfeeds = HashWithIndifferentAccess.new
    jsonfeeds[:title] = "wiki.rails2u.com"
    jsonfeeds[:link] = "http://wiki.rails2u.com/"
    jsonfeeds[:author] = {
      :name => 'gorou',
      :email => 'hotchpotch☆gmail.com',
      :url => 'http://d.hatena.ne.jp/secondlife/'
    }

    entries = []
    jsonfeeds[:entries] = entries

    # Tmail::TextUtils.time2strでRFC 822の時刻に変換するため利用
    tmt = TMail::TextUtils.dup
    tmt.module_eval 'module_function :time2str'

    pagelist(count).each do |wiki|
      entries << {
        :title => wiki.name,
        :link => url_for(:pagename => wiki.name, :controller => 'wiki', :action => 'show'
),
        :date => tmt.time2str(wiki.timestamp)
      }
    end
    if raw
      prefix = ""
    else
      prefix = 'if (typeof(jsonfeeds) == "undefined") var jsonfeeds = {};'
      prefix << 'jsonfeeds["http://wiki.rails2u.com/index.json" ] = '
    end
    @headers['Content-Type'] = 'text/plain; charset=UTF-8'
    render :text => prefix + jsonfeeds.to_json , :layout => false
  end

タグで読み込む方法でsafari以外の最近のブラウザならxmlhttprequestつかわずに外部のドメインからがつんと読み込んで簡単に使えるのがいいね。del.icio.usがJSON出力したり帰り際に靴を隠された人が実装をほのめかしたり、やっとちらほらJSON使うところがでてきたしこれからはJSONの時代が来る!!!!かも。

*1:パッチあてたrubygemsは http://gorou.zapto.org/kinowiki/index.php?cmd=attach¶m=show&page=ruby%2FRuby+on+Rails%2Forbjson%E3%81%AE%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF&file=ruby-json-1.1.1.1.gem