在Rails 3中生成RSS提要

Jep*_*erg 51 rss ruby-on-rails-3

我正在寻找在Rails 3中生成Feed的最佳实践/标准模式.http://railscasts.com/episodes/87-generating-rss-feeds仍然有效吗?

tom*_*rte 113

首先,现在我建议使用ATOM提要而不是RSS.

ATOM feed的规范提供了比具有国际化,内容类型和其他东西的RSS更多的价值,并且每个现代的feed阅读器都支持它.

有关ATOM vs RSS的更多信息,请访问:


关于编码:

此示例假定:

  • NewsItem使用以下属性调用的模型:
    • title
    • content
    • author_name
  • 该模型(news_items_controller.rb)的控制器,您将添加该feed操作

我们将使用一个构建器模板和Ruby on Rails atom_feed helper,它非常有用.

1.将操作添加到控制器

转到app/controllers/news_items_controller.rb并添加:

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
Run Code Online (Sandbox Code Playgroud)

2.设置构建器模板

现在让我们添加模板来构建feed.

转到app/views/news_items/feed.atom.builder并添加:

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
Run Code Online (Sandbox Code Playgroud)

3.用路线将其连接起来

让我们在http://domain.com/feed上提供Feed

这将默认调用具有ATOM格式的操作并重定向/feed.rss/feed.atom.

转到config/routes.rb并添加:

resources :news_items
match '/feed' => 'news_items#feed',
      :as => :feed,
      :defaults => { :format => 'atom' }
Run Code Online (Sandbox Code Playgroud)

4.在布局上添加指向ATOM和RSS源的链接

最后,剩下的就是将Feed添加到布局中.

转到app/views/layouts/application.html.erb并添加此<head></head>部分:

<%= auto_discovery_link_tag :atom, "/feed" %>
<%= auto_discovery_link_tag :rss, "/feed.rss" %>
Run Code Online (Sandbox Code Playgroud)

可能有一两个错字,所以请告诉我这是否适合你.

  • 如果我想为文章显示图像如何传递图像条目该怎么办? (3认同)
  • @holden - 因为我喜欢重复代码并将其用作多个项目的模块.这样,如果我想要改变某些东西,那就是一次性更改,并且不会影响索引操作逻辑(例如,像在答案中那样禁用Feed格式的分页).个人偏好,两者都同样有效. (2认同)
  • @tomeduarte很好的答案,但我认为我正确地说,基于您建议的路线你提供的auto_discovery_link_tag是不正确的.他们的确应该是"/ feed"和"/feed.rss".我知道你说过可能有拼写错误,所以我确定这只是一个疏忽.:-) (2认同)

hol*_*den 10

我做了类似的事情,但没有创建新动作.

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
Run Code Online (Sandbox Code Playgroud)

除非你有像我这样的特殊代码,否则你不需要在控制器中做任何特殊的事情.例如,我使用的是will_paginate gem,对于原子提要,我不希望它分页,所以我这样做是为了避免这种情况.

调节器

  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
Run Code Online (Sandbox Code Playgroud)