mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
FEATURE: suppress categories from the homepage
This commit is contained in:
parent
a76d1079b2
commit
a501947d67
12 changed files with 116 additions and 135 deletions
|
@ -77,7 +77,8 @@ Discourse.Category = Discourse.Model.extend({
|
||||||
background_url: this.get('background_url'),
|
background_url: this.get('background_url'),
|
||||||
allow_badges: this.get('allow_badges'),
|
allow_badges: this.get('allow_badges'),
|
||||||
custom_fields: this.get('custom_fields'),
|
custom_fields: this.get('custom_fields'),
|
||||||
topic_template: this.get('topic_template')
|
topic_template: this.get('topic_template'),
|
||||||
|
suppress_from_homepage: this.get('suppress_from_homepage'),
|
||||||
},
|
},
|
||||||
type: this.get('id') ? 'PUT' : 'POST'
|
type: this.get('id') ? 'PUT' : 'POST'
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,7 +40,6 @@ function findTopicList(store, filter, filterParams, extras) {
|
||||||
session.setProperties({topicList: null, topicListScrollPosition: null});
|
session.setProperties({topicList: null, topicListScrollPosition: null});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Clean up any string parameters that might slip through
|
// Clean up any string parameters that might slip through
|
||||||
filterParams = filterParams || {};
|
filterParams = filterParams || {};
|
||||||
Ember.keys(filterParams).forEach(function(k) {
|
Ember.keys(filterParams).forEach(function(k) {
|
||||||
|
@ -50,17 +49,7 @@ function findTopicList(store, filter, filterParams, extras) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const findParams = {};
|
return resolve(store.findFiltered('topicList', { filter, params: filterParams || {} }));
|
||||||
Discourse.SiteSettings.top_menu.split('|').forEach(function (i) {
|
|
||||||
if (i.indexOf(filter) === 0) {
|
|
||||||
const exclude = i.split("-");
|
|
||||||
if (exclude && exclude.length === 2) {
|
|
||||||
findParams.exclude_category = exclude[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return resolve(store.findFiltered('topicList', { filter, params:_.extend(findParams, filterParams || {})}));
|
|
||||||
|
|
||||||
}).then(function(list) {
|
}).then(function(list) {
|
||||||
list.set('listParams', filterParams);
|
list.set('listParams', filterParams);
|
||||||
if (tracking) {
|
if (tracking) {
|
||||||
|
|
|
@ -44,4 +44,11 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="field">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
{{input type="checkbox" checked=category.suppress_from_homepage}}
|
||||||
|
{{i18n "category.suppress_from_homepage"}}
|
||||||
|
</label>
|
||||||
|
</section>
|
||||||
|
|
||||||
{{plugin-outlet "category-custom-settings"}}
|
{{plugin-outlet "category-custom-settings"}}
|
||||||
|
|
|
@ -16,6 +16,7 @@ class CategoriesController < ApplicationController
|
||||||
options = {}
|
options = {}
|
||||||
options[:latest_posts] = params[:latest_posts] || SiteSetting.category_featured_topics
|
options[:latest_posts] = params[:latest_posts] || SiteSetting.category_featured_topics
|
||||||
options[:parent_category_id] = params[:parent_category_id]
|
options[:parent_category_id] = params[:parent_category_id]
|
||||||
|
options[:is_homepage] = current_homepage == "categories".freeze
|
||||||
|
|
||||||
@list = CategoryList.new(guardian, options)
|
@list = CategoryList.new(guardian, options)
|
||||||
@list.draft_key = Draft::NEW_TOPIC
|
@list.draft_key = Draft::NEW_TOPIC
|
||||||
|
@ -24,7 +25,7 @@ class CategoriesController < ApplicationController
|
||||||
|
|
||||||
discourse_expires_in 1.minute
|
discourse_expires_in 1.minute
|
||||||
|
|
||||||
unless current_homepage == 'categories'
|
unless current_homepage == "categories"
|
||||||
@title = I18n.t('js.filters.categories.title')
|
@title = I18n.t('js.filters.categories.title')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -139,6 +140,7 @@ class CategoriesController < ApplicationController
|
||||||
:position,
|
:position,
|
||||||
:email_in,
|
:email_in,
|
||||||
:email_in_allow_strangers,
|
:email_in_allow_strangers,
|
||||||
|
:suppress_from_homepage,
|
||||||
:parent_category_id,
|
:parent_category_id,
|
||||||
:auto_close_hours,
|
:auto_close_hours,
|
||||||
:auto_close_based_on_last_post,
|
:auto_close_based_on_last_post,
|
||||||
|
|
|
@ -5,36 +5,34 @@ class ListController < ApplicationController
|
||||||
|
|
||||||
skip_before_filter :check_xhr
|
skip_before_filter :check_xhr
|
||||||
|
|
||||||
@@categories = [
|
before_filter :set_category, only: [
|
||||||
# filtered topics lists
|
# filtered topics lists
|
||||||
Discourse.filters.map { |f| "category_#{f}".to_sym },
|
Discourse.filters.map { |f| :"category_#{f}" },
|
||||||
Discourse.filters.map { |f| "category_none_#{f}".to_sym },
|
Discourse.filters.map { |f| :"category_none_#{f}" },
|
||||||
Discourse.filters.map { |f| "parent_category_category_#{f}".to_sym },
|
Discourse.filters.map { |f| :"parent_category_category_#{f}" },
|
||||||
Discourse.filters.map { |f| "parent_category_category_none_#{f}".to_sym },
|
Discourse.filters.map { |f| :"parent_category_category_none_#{f}" },
|
||||||
# top summaries
|
# top summaries
|
||||||
:category_top,
|
:category_top,
|
||||||
:category_none_top,
|
:category_none_top,
|
||||||
:parent_category_category_top,
|
:parent_category_category_top,
|
||||||
# top pages (ie. with a period)
|
# top pages (ie. with a period)
|
||||||
TopTopic.periods.map { |p| "category_top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
||||||
TopTopic.periods.map { |p| "category_none_top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
||||||
TopTopic.periods.map { |p| "parent_category_category_top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
||||||
# category feeds
|
# category feeds
|
||||||
:category_feed,
|
:category_feed,
|
||||||
].flatten
|
].flatten
|
||||||
|
|
||||||
before_filter :set_category, only: @@categories
|
|
||||||
|
|
||||||
before_filter :ensure_logged_in, except: [
|
before_filter :ensure_logged_in, except: [
|
||||||
:topics_by,
|
:topics_by,
|
||||||
# anonymous filters
|
# anonymous filters
|
||||||
Discourse.anonymous_filters,
|
Discourse.anonymous_filters,
|
||||||
Discourse.anonymous_filters.map { |f| "#{f}_feed".to_sym },
|
Discourse.anonymous_filters.map { |f| "#{f}_feed" },
|
||||||
# anonymous categorized filters
|
# anonymous categorized filters
|
||||||
Discourse.anonymous_filters.map { |f| "category_#{f}".to_sym },
|
Discourse.anonymous_filters.map { |f| :"category_#{f}" },
|
||||||
Discourse.anonymous_filters.map { |f| "category_none_#{f}".to_sym },
|
Discourse.anonymous_filters.map { |f| :"category_none_#{f}" },
|
||||||
Discourse.anonymous_filters.map { |f| "parent_category_category_#{f}".to_sym },
|
Discourse.anonymous_filters.map { |f| :"parent_category_category_#{f}" },
|
||||||
Discourse.anonymous_filters.map { |f| "parent_category_category_none_#{f}".to_sym },
|
Discourse.anonymous_filters.map { |f| :"parent_category_category_none_#{f}" },
|
||||||
# category feeds
|
# category feeds
|
||||||
:category_feed,
|
:category_feed,
|
||||||
# top summaries
|
# top summaries
|
||||||
|
@ -43,14 +41,14 @@ class ListController < ApplicationController
|
||||||
:category_none_top,
|
:category_none_top,
|
||||||
:parent_category_category_top,
|
:parent_category_category_top,
|
||||||
# top pages (ie. with a period)
|
# top pages (ie. with a period)
|
||||||
TopTopic.periods.map { |p| "top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"top_#{p}" },
|
||||||
TopTopic.periods.map { |p| "category_top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
||||||
TopTopic.periods.map { |p| "category_none_top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
||||||
TopTopic.periods.map { |p| "parent_category_category_top_#{p}".to_sym },
|
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
||||||
].flatten
|
].flatten
|
||||||
|
|
||||||
# Create our filters
|
# Create our filters
|
||||||
Discourse.filters.each_with_index do |filter, idx|
|
Discourse.filters.each do |filter|
|
||||||
define_method(filter) do |options = nil|
|
define_method(filter) do |options = nil|
|
||||||
list_opts = build_topic_list_options
|
list_opts = build_topic_list_options
|
||||||
list_opts.merge!(options) if options
|
list_opts.merge!(options) if options
|
||||||
|
@ -60,6 +58,10 @@ class ListController < ApplicationController
|
||||||
list_opts[:no_definitions] = true
|
list_opts[:no_definitions] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if filter.to_s == current_homepage
|
||||||
|
list_opts.merge!(exclude_category_ids: get_excluded_category_ids(list_opts[:category]))
|
||||||
|
end
|
||||||
|
|
||||||
list = TopicQuery.new(user, list_opts).public_send("list_#{filter}")
|
list = TopicQuery.new(user, list_opts).public_send("list_#{filter}")
|
||||||
list.more_topics_url = construct_url_with(:next, list_opts)
|
list.more_topics_url = construct_url_with(:next, list_opts)
|
||||||
list.prev_topics_url = construct_url_with(:prev, list_opts)
|
list.prev_topics_url = construct_url_with(:prev, list_opts)
|
||||||
|
@ -83,34 +85,20 @@ class ListController < ApplicationController
|
||||||
|
|
||||||
define_method("category_#{filter}") do
|
define_method("category_#{filter}") do
|
||||||
canonical_url "#{Discourse.base_url}#{@category.url}"
|
canonical_url "#{Discourse.base_url}#{@category.url}"
|
||||||
self.send(filter, { category: @category.id })
|
self.send(filter, category: @category.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("category_none_#{filter}") do
|
define_method("category_none_#{filter}") do
|
||||||
self.send(filter, { category: @category.id, no_subcategories: true })
|
self.send(filter, category: @category.id, no_subcategories: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("parent_category_category_#{filter}") do
|
define_method("parent_category_category_#{filter}") do
|
||||||
canonical_url "#{Discourse.base_url}#{@category.url}"
|
canonical_url "#{Discourse.base_url}#{@category.url}"
|
||||||
self.send(filter, { category: @category.id })
|
self.send(filter, category: @category.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("parent_category_category_none_#{filter}") do
|
define_method("parent_category_category_none_#{filter}") do
|
||||||
self.send(filter, { category: @category.id })
|
self.send(filter, category: @category.id)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Discourse.feed_filters.each do |filter|
|
|
||||||
define_method("#{filter}_feed") do
|
|
||||||
discourse_expires_in 1.minute
|
|
||||||
|
|
||||||
@title = "#{SiteSetting.title} - #{I18n.t("rss_description.#{filter}")}"
|
|
||||||
@link = "#{Discourse.base_url}/#{filter}"
|
|
||||||
@description = I18n.t("rss_description.#{filter}")
|
|
||||||
@atom_link = "#{Discourse.base_url}/#{filter}.rss"
|
|
||||||
@topic_list = TopicQuery.new(nil, order: 'created').public_send("list_#{filter}")
|
|
||||||
|
|
||||||
render 'list', formats: [:rss]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,14 +115,26 @@ class ListController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def latest_feed
|
||||||
|
discourse_expires_in 1.minute
|
||||||
|
|
||||||
|
@title = "#{SiteSetting.title} - #{I18n.t("rss_description.latest")}"
|
||||||
|
@link = "#{Discourse.base_url}/latest"
|
||||||
|
@atom_link = "#{Discourse.base_url}/latest.rss"
|
||||||
|
@description = I18n.t("rss_description.latest")
|
||||||
|
@topic_list = TopicQuery.new(nil, order: 'created').list_latest
|
||||||
|
|
||||||
|
render 'list', formats: [:rss]
|
||||||
|
end
|
||||||
|
|
||||||
def category_feed
|
def category_feed
|
||||||
guardian.ensure_can_see!(@category)
|
guardian.ensure_can_see!(@category)
|
||||||
discourse_expires_in 1.minute
|
discourse_expires_in 1.minute
|
||||||
|
|
||||||
@title = @category.name
|
@title = @category.name
|
||||||
@link = "#{Discourse.base_url}#{@category.url}"
|
@link = "#{Discourse.base_url}#{@category.url}"
|
||||||
@description = "#{I18n.t('topics_in_category', category: @category.name)} #{@category.description}"
|
|
||||||
@atom_link = "#{Discourse.base_url}#{@category.url}.rss"
|
@atom_link = "#{Discourse.base_url}#{@category.url}.rss"
|
||||||
|
@description = "#{I18n.t('topics_in_category', category: @category.name)} #{@category.description}"
|
||||||
@topic_list = TopicQuery.new.list_new_in_category(@category)
|
@topic_list = TopicQuery.new.list_new_in_category(@category)
|
||||||
|
|
||||||
render 'list', formats: [:rss]
|
render 'list', formats: [:rss]
|
||||||
|
@ -147,15 +147,15 @@ class ListController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_top
|
def category_top
|
||||||
top({ category: @category.id })
|
top(category: @category.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_none_top
|
def category_none_top
|
||||||
top({ category: @category.id, no_subcategories: true })
|
top(category: @category.id, no_subcategories: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent_category_category_top
|
def parent_category_category_top
|
||||||
top({ category: @category.id })
|
top(category: @category.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
TopTopic.periods.each do |period|
|
TopTopic.periods.each do |period|
|
||||||
|
@ -163,6 +163,11 @@ class ListController < ApplicationController
|
||||||
top_options = build_topic_list_options
|
top_options = build_topic_list_options
|
||||||
top_options.merge!(options) if options
|
top_options.merge!(options) if options
|
||||||
top_options[:per_page] = SiteSetting.topics_per_period_in_top_page
|
top_options[:per_page] = SiteSetting.topics_per_period_in_top_page
|
||||||
|
|
||||||
|
if "top".freeze == current_homepage
|
||||||
|
top_options.merge!(exclude_category_ids: get_excluded_category_ids(top_options[:category]))
|
||||||
|
end
|
||||||
|
|
||||||
user = list_target_user
|
user = list_target_user
|
||||||
list = TopicQuery.new(user, top_options).list_top_for(period)
|
list = TopicQuery.new(user, top_options).list_top_for(period)
|
||||||
list.for_period = period
|
list.for_period = period
|
||||||
|
@ -177,15 +182,15 @@ class ListController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("category_top_#{period}") do
|
define_method("category_top_#{period}") do
|
||||||
self.send("top_#{period}", { category: @category.id })
|
self.send("top_#{period}", category: @category.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("category_none_top_#{period}") do
|
define_method("category_none_top_#{period}") do
|
||||||
self.send("top_#{period}", { category: @category.id, no_subcategories: true })
|
self.send("top_#{period}", category: @category.id, no_subcategories: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("parent_category_category_top_#{period}") do
|
define_method("parent_category_category_top_#{period}") do
|
||||||
self.send("top_#{period}", { category: @category.id })
|
self.send("top_#{period}", category: @category.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -204,16 +209,15 @@ class ListController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def page_params(opts = nil)
|
def page_params(opts = nil)
|
||||||
opts ||= {}
|
opts ||= {}
|
||||||
route_params = {format: 'json'}
|
route_params = { format: 'json' }
|
||||||
route_params[:category] = @category.slug_for_url if @category
|
route_params[:category] = @category.slug_for_url if @category
|
||||||
route_params[:parent_category] = @category.parent_category.slug_for_url if @category && @category.parent_category
|
route_params[:parent_category] = @category.parent_category.slug_for_url if @category && @category.parent_category
|
||||||
route_params[:order] = opts[:order] if opts[:order].present?
|
route_params[:order] = opts[:order] if opts[:order].present?
|
||||||
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
|
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
|
||||||
route_params
|
route_params
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -235,11 +239,10 @@ class ListController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_topic_list_options
|
def build_topic_list_options
|
||||||
# exclude_category = 1. from params / 2. parsed from top menu / 3. nil
|
|
||||||
options = {
|
options = {
|
||||||
page: params[:page],
|
page: params[:page],
|
||||||
topic_ids: param_to_integer_list(:topic_ids),
|
topic_ids: param_to_integer_list(:topic_ids),
|
||||||
exclude_category: (params[:exclude_category] || select_menu_item.try(:filter)),
|
exclude_category_ids: params[:exclude_category_ids],
|
||||||
category: params[:category],
|
category: params[:category],
|
||||||
order: params[:order],
|
order: params[:order],
|
||||||
ascending: params[:ascending],
|
ascending: params[:ascending],
|
||||||
|
@ -257,17 +260,6 @@ class ListController < ApplicationController
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
def select_menu_item
|
|
||||||
menu_item = SiteSetting.top_menu_items.select do |mu|
|
|
||||||
(mu.has_specific_category? && mu.specific_category == @category.try(:slug)) ||
|
|
||||||
action_name == mu.name ||
|
|
||||||
(action_name.include?("top") && mu.name == "top")
|
|
||||||
end.first
|
|
||||||
|
|
||||||
menu_item = nil if menu_item.try(:has_specific_category?) && menu_item.specific_category == @category.try(:slug)
|
|
||||||
menu_item
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_target_user
|
def list_target_user
|
||||||
if params[:user_id] && guardian.is_staff?
|
if params[:user_id] && guardian.is_staff?
|
||||||
User.find(params[:user_id].to_i)
|
User.find(params[:user_id].to_i)
|
||||||
|
@ -290,25 +282,16 @@ class ListController < ApplicationController
|
||||||
url.sub('.json?','?')
|
url.sub('.json?','?')
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_top_lists(options)
|
def get_excluded_category_ids(current_category=nil)
|
||||||
top = TopLists.new
|
exclude_category_ids = Category.where(suppress_from_homepage: true)
|
||||||
|
exclude_category_ids = exclude_category_ids.where.not(id: current_category) if current_category
|
||||||
options[:per_page] = SiteSetting.topics_per_period_in_top_summary
|
exclude_category_ids.pluck(:id)
|
||||||
topic_query = TopicQuery.new(current_user, options)
|
|
||||||
|
|
||||||
periods = [ListController.best_period_for(current_user.try(:previous_visit_at), options[:category])]
|
|
||||||
|
|
||||||
periods.each { |period| top.send("#{period}=", topic_query.list_top_for(period)) }
|
|
||||||
|
|
||||||
top
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.best_period_for(previous_visit_at, category_id=nil)
|
def self.best_period_for(previous_visit_at, category_id=nil)
|
||||||
best_periods_for(previous_visit_at).each do |period|
|
best_periods_for(previous_visit_at).each do |period|
|
||||||
top_topics = TopTopic.where("#{period}_score > 0")
|
top_topics = TopTopic.where("#{period}_score > 0")
|
||||||
if category_id
|
top_topics = top_topics.joins(:topic).where("topics.category_id = ?", category_id) if category_id
|
||||||
top_topics = top_topics.joins(:topic).where("topics.category_id = ?", category_id)
|
|
||||||
end
|
|
||||||
return period if top_topics.count >= SiteSetting.topics_per_period_in_top_page
|
return period if top_topics.count >= SiteSetting.topics_per_period_in_top_page
|
||||||
end
|
end
|
||||||
# default period is yearly
|
# default period is yearly
|
||||||
|
@ -318,8 +301,8 @@ class ListController < ApplicationController
|
||||||
def self.best_periods_for(date)
|
def self.best_periods_for(date)
|
||||||
date ||= 1.year.ago
|
date ||= 1.year.ago
|
||||||
periods = []
|
periods = []
|
||||||
periods << :daily if date > 8.days.ago
|
periods << :daily if date > 8.days.ago
|
||||||
periods << :weekly if date > 35.days.ago
|
periods << :weekly if date > 35.days.ago
|
||||||
periods << :monthly if date > 180.days.ago
|
periods << :monthly if date > 180.days.ago
|
||||||
periods << :yearly
|
periods << :yearly
|
||||||
periods
|
periods
|
||||||
|
|
|
@ -66,6 +66,8 @@ class CategoryList
|
||||||
@categories = @categories.where('categories.parent_category_id = ?', @options[:parent_category_id].to_i)
|
@categories = @categories.where('categories.parent_category_id = ?', @options[:parent_category_id].to_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@categories = @categories.where(suppress_from_homepage: false) if @options[:is_homepage]
|
||||||
|
|
||||||
if SiteSetting.fixed_category_positions
|
if SiteSetting.fixed_category_positions
|
||||||
@categories = @categories.order('position ASC').order('id ASC')
|
@categories = @categories.order('position ASC').order('id ASC')
|
||||||
else
|
else
|
||||||
|
|
|
@ -8,6 +8,7 @@ class CategorySerializer < BasicCategorySerializer
|
||||||
:position,
|
:position,
|
||||||
:email_in,
|
:email_in,
|
||||||
:email_in_allow_strangers,
|
:email_in_allow_strangers,
|
||||||
|
:suppress_from_homepage,
|
||||||
:can_delete,
|
:can_delete,
|
||||||
:cannot_delete_reason,
|
:cannot_delete_reason,
|
||||||
:allow_badges,
|
:allow_badges,
|
||||||
|
@ -56,4 +57,8 @@ class CategorySerializer < BasicCategorySerializer
|
||||||
scope && scope.can_edit?(object)
|
scope && scope.can_edit?(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def include_suppress_from_homepage?
|
||||||
|
scope && scope.can_edit?(object)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1539,6 +1539,7 @@ en:
|
||||||
email_in_allow_strangers: "Accept emails from anonymous users with no accounts"
|
email_in_allow_strangers: "Accept emails from anonymous users with no accounts"
|
||||||
email_in_disabled: "Posting new topics via email is disabled in the Site Settings. To enable posting new topics via email, "
|
email_in_disabled: "Posting new topics via email is disabled in the Site Settings. To enable posting new topics via email, "
|
||||||
email_in_disabled_click: 'enable the "email in" setting.'
|
email_in_disabled_click: 'enable the "email in" setting.'
|
||||||
|
suppress_from_homepage: "Suppress this category from the homepage."
|
||||||
allow_badges_label: "Allow badges to be awarded in this category"
|
allow_badges_label: "Allow badges to be awarded in this category"
|
||||||
edit_permissions: "Edit Permissions"
|
edit_permissions: "Edit Permissions"
|
||||||
add_permission: "Add Permission"
|
add_permission: "Add Permission"
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddSuppressFromHomepageToCategory < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :categories, :suppress_from_homepage, :boolean, default: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -64,18 +64,10 @@ module Discourse
|
||||||
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks]
|
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.feed_filters
|
|
||||||
@feed_filters ||= [:latest]
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.anonymous_filters
|
def self.anonymous_filters
|
||||||
@anonymous_filters ||= [:latest, :top, :categories]
|
@anonymous_filters ||= [:latest, :top, :categories]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.logged_in_filters
|
|
||||||
@logged_in_filters ||= Discourse.filters - Discourse.anonymous_filters
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.top_menu_items
|
def self.top_menu_items
|
||||||
@top_menu_items ||= Discourse.filters + [:category, :categories, :top]
|
@top_menu_items ||= Discourse.filters + [:category, :categories, :top]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#
|
#
|
||||||
# Helps us find topics. Returns a TopicList object containing the topics
|
# Helps us find topics.
|
||||||
# found.
|
# Returns a TopicList object containing the topics found.
|
||||||
#
|
#
|
||||||
|
|
||||||
require_dependency 'topic_list'
|
require_dependency 'topic_list'
|
||||||
require_dependency 'suggested_topics_builder'
|
require_dependency 'suggested_topics_builder'
|
||||||
require_dependency 'topic_query_sql'
|
require_dependency 'topic_query_sql'
|
||||||
|
|
||||||
class TopicQuery
|
class TopicQuery
|
||||||
# Could be rewritten to %i if Ruby 1.9 is no longer supported
|
# Could be rewritten to %i if Ruby 1.9 is no longer supported
|
||||||
VALID_OPTIONS = %w(except_topic_ids
|
VALID_OPTIONS = %i(except_topic_ids
|
||||||
exclude_category
|
exclude_category_ids
|
||||||
limit
|
limit
|
||||||
page
|
page
|
||||||
per_page
|
per_page
|
||||||
|
@ -27,8 +28,7 @@ class TopicQuery
|
||||||
search
|
search
|
||||||
slow_platform
|
slow_platform
|
||||||
filter
|
filter
|
||||||
q
|
q)
|
||||||
).map(&:to_sym)
|
|
||||||
|
|
||||||
# Maps `order` to a columns in `topics`
|
# Maps `order` to a columns in `topics`
|
||||||
SORTABLE_MAPPING = {
|
SORTABLE_MAPPING = {
|
||||||
|
@ -301,14 +301,17 @@ class TopicQuery
|
||||||
if options[:no_subcategories]
|
if options[:no_subcategories]
|
||||||
result = result.where('categories.id = ?', category_id)
|
result = result.where('categories.id = ?', category_id)
|
||||||
else
|
else
|
||||||
result = result.where('categories.id = ? or (categories.parent_category_id = ? AND categories.topic_id <> topics.id)', category_id, category_id)
|
result = result.where('categories.id = :category_id OR (categories.parent_category_id = :category_id AND categories.topic_id <> topics.id)', category_id: category_id)
|
||||||
end
|
end
|
||||||
result = result.references(:categories)
|
result = result.references(:categories)
|
||||||
end
|
end
|
||||||
|
|
||||||
result = apply_ordering(result, options)
|
result = apply_ordering(result, options)
|
||||||
result = result.listable_topics.includes(:category)
|
result = result.listable_topics.includes(:category)
|
||||||
result = result.where('categories.name is null or categories.name <> ?', options[:exclude_category]).references(:categories) if options[:exclude_category]
|
|
||||||
|
if options[:exclude_category_ids] && options[:exclude_category_ids].is_a?(Array) && options[:exclude_category_ids].size > 0
|
||||||
|
result = result.where("categories.id NOT IN (?)", options[:exclude_category_ids]).references(:categories)
|
||||||
|
end
|
||||||
|
|
||||||
# Don't include the category topics if excluded
|
# Don't include the category topics if excluded
|
||||||
if options[:no_definitions]
|
if options[:no_definitions]
|
||||||
|
@ -393,19 +396,20 @@ class TopicQuery
|
||||||
|
|
||||||
def remove_muted_categories(list, user, opts=nil)
|
def remove_muted_categories(list, user, opts=nil)
|
||||||
category_id = get_category_id(opts[:exclude]) if opts
|
category_id = get_category_id(opts[:exclude]) if opts
|
||||||
|
|
||||||
if user
|
if user
|
||||||
list = list.where("NOT EXISTS(
|
list = list.references("cu")
|
||||||
SELECT 1 FROM category_users cu
|
.where("
|
||||||
WHERE cu.user_id = ? AND
|
NOT EXISTS (
|
||||||
cu.category_id = topics.category_id AND
|
SELECT 1
|
||||||
cu.notification_level = ? AND
|
FROM category_users cu
|
||||||
cu.category_id <> ?
|
WHERE cu.user_id = :user_id
|
||||||
)",
|
AND cu.category_id = topics.category_id
|
||||||
user.id,
|
AND cu.notification_level = :muted
|
||||||
CategoryUser.notification_levels[:muted],
|
AND cu.category_id <> :category_id
|
||||||
category_id || -1
|
)", user_id: user.id,
|
||||||
)
|
muted: CategoryUser.notification_levels[:muted],
|
||||||
.references('cu')
|
category_id: category_id || -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
list
|
list
|
||||||
|
|
|
@ -32,12 +32,6 @@ describe ListController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Discourse.logged_in_filters.each do |filter|
|
|
||||||
context "#{filter}" do
|
|
||||||
it { expect { xhr :get, filter }.to raise_error(Discourse::NotLoggedIn) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'allows users to filter on a set of topic ids' do
|
it 'allows users to filter on a set of topic ids' do
|
||||||
p = create_post
|
p = create_post
|
||||||
|
|
||||||
|
@ -51,14 +45,10 @@ describe ListController do
|
||||||
|
|
||||||
describe 'RSS feeds' do
|
describe 'RSS feeds' do
|
||||||
|
|
||||||
Discourse.feed_filters.each do |filter|
|
it 'renders RSS' do
|
||||||
|
get "latest_feed", format: :rss
|
||||||
it 'renders RSS' do
|
expect(response).to be_success
|
||||||
get "#{filter}_feed", format: :rss
|
expect(response.content_type).to eq('application/rss+xml')
|
||||||
expect(response).to be_success
|
|
||||||
expect(response.content_type).to eq('application/rss+xml')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue