Skip to content

Commit fd240c1

Browse files
committed
RSS for topics in a category
Creates a new route for category RSS
1 parent 0c8c41b commit fd240c1

11 files changed

Lines changed: 85 additions & 12 deletions

File tree

app/controllers/list_controller.rb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class ListController < ApplicationController
22

3-
before_filter :ensure_logged_in, except: [:index, :category]
3+
before_filter :ensure_logged_in, except: [:index, :category, :category_feed]
44
skip_before_filter :check_xhr
55

66
# Create our filters
@@ -38,15 +38,24 @@ def category
3838
if params[:category] == Slug.for(SiteSetting.uncategorized_name) or params[:category] == SiteSetting.uncategorized_name
3939
list = query.list_uncategorized
4040
else
41-
category = Category.where("slug = ? or id = ?", params[:category], params[:category].to_i).includes(:featured_users).first
42-
guardian.ensure_can_see!(category)
43-
list = query.list_category(category)
41+
@category = Category.where("slug = ? or id = ?", params[:category], params[:category].to_i).includes(:featured_users).first
42+
guardian.ensure_can_see!(@category)
43+
list = query.list_category(@category)
4444
end
4545

4646
list.more_topics_url = url_for(category_path(params[:category], page: next_page, format: "json"))
4747
respond(list)
4848
end
4949

50+
def category_feed
51+
raise Discourse::InvalidParameters.new('Category RSS of "uncategorized"') if params[:category] == Slug.for(SiteSetting.uncategorized_name) || params[:category] == SiteSetting.uncategorized_name
52+
53+
@category = Category.where("slug = ?", params[:category]).includes(:featured_users).first
54+
guardian.ensure_can_see!(@category)
55+
@topic_list = TopicQuery.new.list_new_in_category(@category)
56+
render 'list', formats: [:rss]
57+
end
58+
5059
protected
5160

5261

app/models/topic.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class Topic < ActiveRecord::Base
6060

6161
scope :listable_topics, lambda { where('topics.archetype <> ?', [Archetype.private_message]) }
6262

63+
scope :by_newest, order('created_at desc, id desc')
64+
6365
# Helps us limit how many favorites can be made in a day
6466
class FavoriteLimiter < RateLimiter
6567
def initialize(user)

app/views/list/list.erb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@
88
<p><a href="<%= @list.more_topics_url.sub('.json?','?') %>"><%= t 'next_page'%></a></p>
99
<% end %>
1010

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

app/views/list/list.rss.erb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
3+
<channel>
4+
<title><%= @category.name %></title>
5+
<link><%= Discourse.base_url %>/category/<%= @category.slug %>.rss</link>
6+
<description><%= t 'topics_in_category', category: @category.name %><%= @category.description %></description>
7+
<atom:link href="<%= Discourse.base_url %>/category/<%= @category.slug %>.rss" rel="self" type="application/rss+xml" />
8+
<% @topic_list.topics.each do |topic| %>
9+
<item>
10+
<title><%= topic.title %></title>
11+
<description><![CDATA[
12+
<p><%= pluralize(topic.posts_count, 'post') %></p>
13+
<p><%= t 'author_wrote', author: topic.posts.first.author_readable %></p>
14+
<%= topic.posts.first.cooked.html_safe %>
15+
]]></description>
16+
<link><%= Discourse.base_url %><%= topic.relative_url %></link>
17+
<pubDate><%= topic.created_at.rfc2822 %></pubDate>
18+
<guid><%= Discourse.base_url %><%= topic.relative_url %></guid>
19+
<source url="<%= Discourse.base_url %><%= topic.relative_url %>.rss"><%= topic.title %></source>
20+
</item>
21+
<% end %>
22+
</channel>
23+
</rss>

app/views/topics/show.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@
2323
<p><%= t 'powered_by' %></p>
2424

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

config/locales/server.en.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ en:
1515
is_invalid: "is invalid; try to be a little more descriptive"
1616
next_page: "next page &rarr;"
1717
by: "By"
18-
rss_feed: "RSS feed of %{topic}"
18+
topics_in_category: "Topics in the '%{category}' category"
19+
rss_posts_in_topic: "RSS feed of '%{topic}'"
20+
rss_topics_in_category: "RSS feed of topics in the '%{category}' category"
21+
author_wrote: "%{author} wrote:"
1922

2023
education:
2124
until_posts:

config/routes.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,13 @@
137137
resources :user_actions
138138
resources :education
139139

140+
get 'category/:category.rss' => 'list#category_feed', format: :rss, as: 'category_feed'
140141
get 'category/:category' => 'list#category'
142+
get 'category/:category' => 'list#category', as: 'category'
143+
get 'category/:category/more' => 'list#category', as: 'category'
144+
get 'categories' => 'categories#index'
141145
get 'popular' => 'list#index'
142146
get 'popular/more' => 'list#index'
143-
get 'categories' => 'categories#index'
144147
get 'favorited' => 'list#favorited'
145148
get 'favorited/more' => 'list#favorited'
146149
get 'read' => 'list#read'
@@ -151,8 +154,6 @@
151154
get 'new/more' => 'list#new'
152155
get 'posted' => 'list#posted'
153156
get 'posted/more' => 'list#posted'
154-
get 'category/:category' => 'list#category', as: 'category'
155-
get 'category/:category/more' => 'list#category', as: 'category'
156157

157158
get 'search' => 'search#query'
158159

lib/topic_query.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ def new_count
114114
new_results(limit: false).count
115115
end
116116

117+
def list_new_in_category(category)
118+
return_list {|l| l.where(category_id: category.id).by_newest.first(25)}
119+
end
120+
117121
protected
118122

119123
def return_list(list_opts={})

spec/components/topic_query_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@
5151
it "returns nothing when filtering by another category" do
5252
topic_query.list_category(Fabricate(:category, name: 'new cat')).topics.should be_blank
5353
end
54+
55+
describe '#list_new_in_category' do
56+
it 'returns only the categorized topic' do
57+
topic_query.list_new_in_category(category).topics.should == [topic_in_cat]
58+
end
59+
end
5460
end
5561

5662
context 'unread / read topics' do

spec/controllers/list_controller_spec.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@
4343
it { should respond_with(:success) }
4444
end
4545

46+
describe 'feed' do
47+
it 'renders RSS' do
48+
get :category_feed, category: category.slug, format: :rss
49+
response.should be_success
50+
response.content_type.should == 'application/rss+xml'
51+
end
52+
end
53+
4654
end
4755

4856
context 'uncategorized' do
@@ -59,8 +67,6 @@
5967

6068
end
6169

62-
63-
6470
end
6571

6672
context 'favorited' do

0 commit comments

Comments
 (0)