2011-01-28 14 views

risposta

114

Prima di tutto, al giorno d'oggi Si consiglia di utilizzare un feed ATOM anziché RSS.

Le specifiche del feed ATOM offrono più valore rispetto a quello RSS con internazionalizzazione, tipi di contenuto e altre cose e che ogni moderno lettore di feed supporta.

Maggiori informazioni su ATOM vs RSS sono disponibili all'indirizzo:


On per la codifica:

Questo esempio presuppone:

  • un modello chiamato NewsItem con i seguenti attributi:
    • title
    • content
    • author_name
  • un controller per quel modello (news_items_controller.rb), per a cui aggiungerai il feed ac

Useremo un modello di builder per questo e il Ruby on Rails atom_feed helper che è di grande utilità.

1. Aggiungere l'azione al controller

Vai a app/controllers/news_items_controller.rb e aggiungere:

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. Imposta il modello costruttore

Ora aggiungiamo il template per costruire il feed.

Vai a app/views/news_items/feed.atom.builder e aggiungere:

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. Filo in su con un percorso

Facciamo i feed disponibili presso http://domain.com/feed

questo chiamerà l'azione con l'atomo formattare per impostazione predefinita e reindirizzare /feed.rss a /feed.atom.

Vai a config/routes.rb e aggiungere:

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

4. Aggiungere il link al feed RSS e Atom sul layout

Infine, tutto ciò che rimane è quello di aggiungere il feed al layout .

Vai a app/views/layouts/application.html.erb e aggiungere la tua <head></head> sezione:

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

Ci può essere un errore di battitura o due in questo, quindi fatemi sapere se questo funziona per voi.

+1

dare credito dove è dovuto, questo è un'implementazione che ho fatto e l'uso in base al largo questo post del blog e le sue osservazioni: http://lindsaar.net/2010/2/12/how -to-make-an-rss-feed-o-atom-feed-in-rails – tomeduarte

+0

ma perché aggiungere un'azione totalmente nuova anziché semplicemente un nuovo formato per dire l'azione indice? – holden

+2

@holden - perché mi piace fare il riutilizzo del codice e usarlo come modulo su diversi progetti. In questo modo, se voglio cambiare qualcosa è una modifica una tantum e non influisce sulla logica di azione dell'indice (ad esempio disabilitando l'impaginazione per i formati di feed come hai fatto nella tua risposta). Preferenza personale, entrambi sono ugualmente validi. – tomeduarte

10

Ho fatto qualcosa di simile ma senza creare una nuova azione.

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 

Non c'è bisogno di fare nulla di speciale nel controller a meno che non si dispone di un codice speciale come ho fatto. Per esempio sto usando la gemma will_paginate e per il feed atom non voglio che impagini, così ho fatto questo per evitarlo.

regolatore

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 
+0

il tuo esempio sembra piuttosto semplice: sono solo questi 2 passaggi per far funzionare il feed atom o ci sono altri? – ubique

+0

@ubique: Ho appena giocato con questo in uno dei miei controller per curiosità. Usa il nuovo formato Rail 3 quindi tutto ciò che dovevo fare era aggiungere: atom al mio respond_to hash - Non avevo nemmeno bisogno di toccare respond_with. Rails ha trovato automagicamente index.atom.builder senza ulteriori modifiche al controller. Sono davvero impressionato da uno sfondo PHP! –

+0

Cosa succede se voglio visualizzare un'immagine per l'articolo come faccio a passare la voce dell'immagine. – Uchenna