Merge pull request #290 from alxndr/category-rss

RSS for topics in a category
This commit is contained in:
Robin Ward 2013-03-01 12:01:26 -08:00
commit d410f043a9
11 changed files with 85 additions and 12 deletions

View file

@ -1,6 +1,6 @@
class ListController < ApplicationController
before_filter :ensure_logged_in, except: [:index, :category]
before_filter :ensure_logged_in, except: [:index, :category, :category_feed]
skip_before_filter :check_xhr
# Create our filters
@ -38,15 +38,24 @@ class ListController < ApplicationController
if params[:category] == Slug.for(SiteSetting.uncategorized_name) or params[:category] == SiteSetting.uncategorized_name
list = query.list_uncategorized
else
category = Category.where("slug = ? or id = ?", params[:category], params[:category].to_i).includes(:featured_users).first
guardian.ensure_can_see!(category)
list = query.list_category(category)
@category = Category.where("slug = ? or id = ?", params[:category], params[:category].to_i).includes(:featured_users).first
guardian.ensure_can_see!(@category)
list = query.list_category(@category)
end
list.more_topics_url = url_for(category_path(params[:category], page: next_page, format: "json"))
respond(list)
end
def category_feed
raise Discourse::InvalidParameters.new('Category RSS of "uncategorized"') if params[:category] == Slug.for(SiteSetting.uncategorized_name) || params[:category] == SiteSetting.uncategorized_name
@category = Category.where("slug = ?", params[:category]).includes(:featured_users).first
guardian.ensure_can_see!(@category)
@topic_list = TopicQuery.new.list_new_in_category(@category)
render 'list', formats: [:rss]
end
protected

View file

@ -60,6 +60,8 @@ class Topic < ActiveRecord::Base
scope :listable_topics, lambda { where('topics.archetype <> ?', [Archetype.private_message]) }
scope :by_newest, order('created_at desc, id desc')
# Helps us limit how many favorites can be made in a day
class FavoriteLimiter < RateLimiter
def initialize(user)

View file

@ -9,3 +9,9 @@
<% end %>
<p><%= t 'powered_by' %></p>
<% if @category %>
<% content_for :head do %>
<%= auto_discovery_link_tag(@category, {action: :category_feed, format: :rss}, title: t('rss_topics_in_category', category: @category.name), type: 'application/rss+xml') %>
<% end %>
<% end %>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><%= @category.name %></title>
<link><%= Discourse.base_url %>/category/<%= @category.slug %>.rss</link>
<description><%= t 'topics_in_category', category: @category.name %><%= @category.description %></description>
<atom:link href="<%= Discourse.base_url %>/category/<%= @category.slug %>.rss" rel="self" type="application/rss+xml" />
<% @topic_list.topics.each do |topic| %>
<item>
<title><%= topic.title %></title>
<description><![CDATA[
<p><%= pluralize(topic.posts_count, 'post') %></p>
<p><%= t 'author_wrote', author: topic.posts.first.author_readable %></p>
<%= topic.posts.first.cooked.html_safe %>
]]></description>
<link><%= Discourse.base_url %><%= topic.relative_url %></link>
<pubDate><%= topic.created_at.rfc2822 %></pubDate>
<guid><%= Discourse.base_url %><%= topic.relative_url %></guid>
<source url="<%= Discourse.base_url %><%= topic.relative_url %>.rss"><%= topic.title %></source>
</item>
<% end %>
</channel>
</rss>

View file

@ -23,5 +23,5 @@
<p><%= t 'powered_by' %></p>
<% content_for :head do %>
<%= auto_discovery_link_tag(@topic_view, {action: :feed, format: :rss}, title: t('rss_feed', topic: @topic_view.title), type: 'application/rss+xml') %>
<%= auto_discovery_link_tag(@topic_view, {action: :feed, format: :rss}, title: t('rss_posts_in_topic', topic: @topic_view.title), type: 'application/rss+xml') %>
<% end %>

View file

@ -15,7 +15,10 @@ en:
is_invalid: "is invalid; try to be a little more descriptive"
next_page: "next page &rarr;"
by: "By"
rss_feed: "RSS feed of %{topic}"
topics_in_category: "Topics in the '%{category}' category"
rss_posts_in_topic: "RSS feed of '%{topic}'"
rss_topics_in_category: "RSS feed of topics in the '%{category}' category"
author_wrote: "%{author} wrote:"
education:
until_posts:

View file

@ -137,10 +137,13 @@ Discourse::Application.routes.draw do
resources :user_actions
resources :education
get 'category/:category.rss' => 'list#category_feed', format: :rss, as: 'category_feed'
get 'category/:category' => 'list#category'
get 'category/:category' => 'list#category', as: 'category'
get 'category/:category/more' => 'list#category', as: 'category'
get 'categories' => 'categories#index'
get 'popular' => 'list#index'
get 'popular/more' => 'list#index'
get 'categories' => 'categories#index'
get 'favorited' => 'list#favorited'
get 'favorited/more' => 'list#favorited'
get 'read' => 'list#read'
@ -151,8 +154,6 @@ Discourse::Application.routes.draw do
get 'new/more' => 'list#new'
get 'posted' => 'list#posted'
get 'posted/more' => 'list#posted'
get 'category/:category' => 'list#category', as: 'category'
get 'category/:category/more' => 'list#category', as: 'category'
get 'search' => 'search#query'

View file

@ -114,6 +114,10 @@ class TopicQuery
new_results(limit: false).count
end
def list_new_in_category(category)
return_list {|l| l.where(category_id: category.id).by_newest.first(25)}
end
protected
def return_list(list_opts={})

View file

@ -51,6 +51,12 @@ describe TopicQuery do
it "returns nothing when filtering by another category" do
topic_query.list_category(Fabricate(:category, name: 'new cat')).topics.should be_blank
end
describe '#list_new_in_category' do
it 'returns only the categorized topic' do
topic_query.list_new_in_category(category).topics.should == [topic_in_cat]
end
end
end
context 'unread / read topics' do

View file

@ -43,6 +43,14 @@ describe ListController do
it { should respond_with(:success) }
end
describe 'feed' do
it 'renders RSS' do
get :category_feed, category: category.slug, format: :rss
response.should be_success
response.content_type.should == 'application/rss+xml'
end
end
end
context 'uncategorized' do
@ -59,8 +67,6 @@ describe ListController do
end
end
context 'favorited' do

View file

@ -1033,4 +1033,17 @@ describe Topic do
end
describe 'scopes' do
describe '#by_most_recently_created' do
it 'returns topics ordered by created_at desc, id desc' do
now = Time.now
a = Fabricate(:topic, created_at: now - 2.minutes)
b = Fabricate(:topic, created_at: now)
c = Fabricate(:topic, created_at: now)
d = Fabricate(:topic, created_at: now - 2.minutes)
Topic.by_newest.should == [c,b,d,a]
end
end
end
end