Je suis à la recherche d'une meilleure pratique/un modèle standard pour générer des flux dans Rails 3. Est-ce que http://railscasts.com/episodes/87-generating-rss-feeds encore valable ?
Réponses
Trop de publicités?Tout d'abord, de nos jours Je recommande d'utiliser un flux ATOM au lieu d'un flux RSS. .
La spécification du flux ATOM offre plus de valeur que celle du flux RSS en ce qui concerne l'internationalisation, les types de contenu et d'autres éléments. et tous les lecteurs de flux modernes le prennent en charge.
Vous trouverez plus d'informations sur ATOM et RSS à l'adresse suivante :
- le site Entrée ATOM de Wikipedia
- Blogueur PRO et Zone de libre-échange des articles de blog sur le sujet
Passons au codage :
Cet exemple suppose :
- un modèle appelé
NewsItem
avec les attributs suivants :title
content
author_name
- un contrôleur pour ce modèle (
news_items_controller.rb
), à laquelle vous ajouterez lefeed
action
Nous utiliserons un modèle de construction pour ce faire et l'application Ruby on Rails aide atom_feed qui est d'une grande utilité.
1. Ajoutez l'action au contrôleur
Aller à 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 construction
Maintenant, ajoutons le modèle pour construire le flux.
Aller à 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. Connectez-le avec une route
Rendons les flux disponibles à http://domain.com/feed
Ceci appellera l'action avec le format ATOM par défaut et redirigera /feed.rss
à /feed.atom
.
Aller à config/routes.rb
et ajoutez :
resources :news_items
match '/feed' => 'news_items#feed',
:as => :feed,
:defaults => { :format => 'atom' }
4. Ajouter le lien vers les flux ATOM et RSS sur la mise en page
Enfin, il ne reste plus qu'à ajouter le flux à la mise en page.
Aller à app/views/layouts/application.html.erb
et ajoutez ceci à votre <head></head>
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 une 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 quoi que ce soit de spécial dans le contrôleur, sauf si vous avez un code spécial comme moi. Par exemple, j'utilise la gemme will_paginate et pour le flux atomique je ne veux pas qu'il pagine donc j'ai fait ceci pour éviter cela.
contrôleur
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