Générer un stream RSS dans Rails 3

Je recherche un modèle standard / de bonnes pratiques pour générer des stream dans Rails 3. Est-ce que http://railscasts.com/episodes/87-generating-rss-feeds est toujours valide?

Tout d’abord, je recommande aujourd’hui d’ utiliser un stream ATOM au lieu de RSS .

La spécification du stream ATOM offre plus de valeur que le stream RSS avec l’internationalisation, les types de contenu et d’autres choses, et chaque lecteur de stream moderne le prend en charge.

Plus d’infos sur ATOM vs RSS peut être trouvé à:

  • L’ entrée Wikipedia de l’ATOM
  • Blogues PRO Blogger et Free Marketing Zone sur le sujet

Sur le codage:

Cet exemple suppose:

  • un modèle appelé NewsItem avec les atsortingbuts suivants:
    • title
    • content
    • author_name
  • un contrôleur pour ce modèle ( news_items_controller.rb ), auquel vous appendez l’action de feed

Nous utiliserons un modèle de générateur pour ceci et le helper Ruby on Rails atom_feed qui est très utile.

1. Ajoutez l’action au contrôleur

Accédez à app/controllers/news_items_controller.rb et ajoutez:

 def feed # this will be the name of the feed displayed on the feed reader @title = "FEED title" # the news items @news_items = NewsItem.order("updated_at desc") # this will be our Feed's update timestamp @updated = @news_items.first.updated_at unless @news_items.empty? respond_to do |format| format.atom { render :layout => false } # we want the RSS feed to redirect permanently to the ATOM feed format.rss { redirect_to feed_path(:format => :atom), :status => :moved_permanently } end end 

2. Configurez votre modèle de générateur

Ajoutons maintenant le modèle pour générer le stream.

Accédez à app/views/news_items/feed.atom.builder et ajoutez:

 atom_feed :language => 'en-US' do |feed| feed.title @title feed.updated @updated @news_items.each do |item| next if item.updated_at.blank? feed.entry( item ) do |entry| entry.url news_item_url(item) entry.title item.title entry.content item.content, :type => 'html' # the strftime is needed to work with Google Reader. entry.updated(item.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ")) entry.author do |author| author.name entry.author_name end end end end 

3. Câbler avec un itinéraire

Faisons en sorte que les stream soient disponibles sur http://domain.com/feed

Cela appellera l’action au format ATOM par défaut et redirecta /feed.rss vers /feed.atom .

Allez dans config/routes.rb et ajoutez:

 resources :news_items match '/feed' => 'news_items#feed', :as => :feed, :defaults => { :format => 'atom' } 

4. Ajoutez le lien vers ATOM et les stream RSS sur la mise en page.

Enfin, il ne rest plus qu’à append le stream à la mise en page.

Accédez à app/views/layouts/application.html.erb et ajoutez-y votre section :

 <%= auto_discovery_link_tag :atom, "/feed" %> <%= auto_discovery_link_tag :rss, "/feed.rss" %> 

Il peut y avoir une ou deux fautes de frappe, alors faites-moi savoir si cela fonctionne pour vous.

J’ai fait quelque chose de similaire mais sans créer de nouvelle action.

index.atom.builder

 atom_feed :language => 'en-US' do |feed| feed.title "Articles" feed.updated Time.now @articles.each do |item| next if item.published_at.blank? feed.entry( item ) do |entry| entry.url article_url(item) entry.title item.title entry.content item.content, :type => 'html' # the strftime is needed to work with Google Reader. entry.updated(item.published_at.strftime("%Y-%m-%dT%H:%M:%SZ")) entry.author item.user.handle end end end 

Vous n’avez pas besoin de faire quelque chose de spécial dans le contrôleur à moins que vous n’ayez un code spécial comme je l’ai fait. Par exemple, j’utilise la gemme will_paginate et pour le stream atom, je ne veux pas la paginer, alors je l’ai fait pour éviter cela.

manette

  def index if current_user && current_user.admin? @articles = Article.paginate :page => params[:page], :order => 'created_at DESC' else respond_to do |format| format.html { @articles = Article.published.paginate :page => params[:page], :order => 'published_at DESC' } format.atom { @articles = Article.published } end end end