FEATURE: add category suppress from latest

In the past we used suppress_from_homepage, it had mixed semantics
it would remove from category list if category list was on home and
unconditionally remove from latest.

New setting explicitly only removes from latest list but leaves the
category list alond
This commit is contained in:
Sam 2018-02-22 09:56:18 +11:00
parent d2b518c61c
commit 720e1965e3
18 changed files with 67 additions and 30 deletions

View File

@ -97,7 +97,7 @@ const Category = RestModel.extend({
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'), suppress_from_latest: this.get('suppress_from_latest'),
all_topics_wiki: this.get('all_topics_wiki'), all_topics_wiki: this.get('all_topics_wiki'),
allowed_tags: this.get('allowed_tags'), allowed_tags: this.get('allowed_tags'),
allowed_tag_groups: this.get('allowed_tag_groups'), allowed_tag_groups: this.get('allowed_tag_groups'),

View File

@ -117,8 +117,8 @@ const TopicTrackingState = Discourse.Model.extend({
} }
if (filter === defaultHomepage()) { if (filter === defaultHomepage()) {
const suppressed_from_homepage_category_ids = Discourse.Site.currentProp("suppressed_from_homepage_category_ids"); const suppressed_from_latest_category_ids = Discourse.Site.currentProp("suppressed_from_latest_category_ids");
if (_.include(suppressed_from_homepage_category_ids, data.payload.category_id)) { if (_.include(suppressed_from_latest_category_ids, data.payload.category_id)) {
return; return;
} }
} }

View File

@ -21,8 +21,8 @@
<section class="field"> <section class="field">
<label> <label>
{{input type="checkbox" checked=category.suppress_from_homepage}} {{input type="checkbox" checked=category.suppress_from_latest}}
{{i18n "category.suppress_from_homepage"}} {{i18n "category.suppress_from_latest"}}
</label> </label>
</section> </section>

View File

@ -61,7 +61,7 @@ class CategoriesController < ApplicationController
topic_options = { topic_options = {
per_page: SiteSetting.categories_topics, per_page: SiteSetting.categories_topics,
no_definitions: true, no_definitions: true,
exclude_category_ids: Category.where(suppress_from_homepage: true).pluck(:id) exclude_category_ids: Category.where(suppress_from_latest: true).pluck(:id)
} }
result = CategoryAndTopicLists.new result = CategoryAndTopicLists.new
@ -235,7 +235,7 @@ class CategoriesController < ApplicationController
:email_in, :email_in,
:email_in_allow_strangers, :email_in_allow_strangers,
:mailinglist_mirror, :mailinglist_mirror,
:suppress_from_homepage, :suppress_from_latest,
:all_topics_wiki, :all_topics_wiki,
:parent_category_id, :parent_category_id,
:auto_close_hours, :auto_close_hours,

View File

@ -63,7 +63,7 @@ class ListController < ApplicationController
if filter == :latest if filter == :latest
list_opts[:no_definitions] = true list_opts[:no_definitions] = true
end end
if filter.to_s == current_homepage if [:latest, :categories].include?(filter)
list_opts[:exclude_category_ids] = get_excluded_category_ids(list_opts[:category]) list_opts[:exclude_category_ids] = get_excluded_category_ids(list_opts[:category])
end end
end end
@ -369,7 +369,7 @@ class ListController < ApplicationController
end end
def get_excluded_category_ids(current_category = nil) def get_excluded_category_ids(current_category = nil)
exclude_category_ids = Category.where(suppress_from_homepage: true) exclude_category_ids = Category.where(suppress_from_latest: true)
exclude_category_ids = exclude_category_ids.where.not(id: current_category) if current_category exclude_category_ids = exclude_category_ids.where.not(id: current_category) if current_category
exclude_category_ids.pluck(:id) exclude_category_ids.pluck(:id)
end end

View File

@ -542,7 +542,7 @@ end
# name_lower :string(50) not null # name_lower :string(50) not null
# auto_close_based_on_last_post :boolean default(FALSE) # auto_close_based_on_last_post :boolean default(FALSE)
# topic_template :text # topic_template :text
# suppress_from_homepage :boolean default(FALSE) # suppress_from_latest :boolean default(FALSE)
# contains_messages :boolean # contains_messages :boolean
# sort_order :string # sort_order :string
# sort_ascending :boolean # sort_ascending :boolean

View File

@ -72,7 +72,6 @@ class CategoryList
subcategories: [:topic_only_relative_url] subcategories: [:topic_only_relative_url]
).secured(@guardian) ).secured(@guardian)
@categories = @categories.where(suppress_from_homepage: false) if @options[:is_homepage]
@categories = @categories.where("categories.parent_category_id = ?", @options[:parent_category_id].to_i) if @options[:parent_category_id].present? @categories = @categories.where("categories.parent_category_id = ?", @options[:parent_category_id].to_i) if @options[:parent_category_id].present?
if SiteSetting.fixed_category_positions if SiteSetting.fixed_category_positions

View File

@ -71,8 +71,8 @@ class Site
end end
end end
def suppressed_from_homepage_category_ids def suppressed_from_latest_category_ids
categories.select { |c| c.suppress_from_homepage == true }.map(&:id) categories.select { |c| c.suppress_from_latest == true }.map(&:id)
end end
def archetypes def archetypes

View File

@ -9,7 +9,7 @@ class CategorySerializer < BasicCategorySerializer
:email_in, :email_in,
:email_in_allow_strangers, :email_in_allow_strangers,
:mailinglist_mirror, :mailinglist_mirror,
:suppress_from_homepage, :suppress_from_latest,
:all_topics_wiki, :all_topics_wiki,
:can_delete, :can_delete,
:cannot_delete_reason, :cannot_delete_reason,
@ -72,7 +72,7 @@ class CategorySerializer < BasicCategorySerializer
scope && scope.can_edit?(object) scope && scope.can_edit?(object)
end end
def include_suppress_from_homepage? def include_suppress_from_latest?
scope && scope.can_edit?(object) scope && scope.can_edit?(object)
end end

View File

@ -16,7 +16,7 @@ class SiteSerializer < ApplicationSerializer
:is_readonly, :is_readonly,
:disabled_plugins, :disabled_plugins,
:user_field_max_length, :user_field_max_length,
:suppressed_from_homepage_category_ids, :suppressed_from_latest_category_ids,
:post_action_types, :post_action_types,
:topic_flag_types, :topic_flag_types,
:can_create_tag, :can_create_tag,

View File

@ -2209,7 +2209,7 @@ en:
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.'
mailinglist_mirror: "Category mirrors a mailing list" mailinglist_mirror: "Category mirrors a mailing list"
suppress_from_homepage: "Suppress this category from the homepage." suppress_from_latest: "Suppress category from latest topics."
show_subcategory_list: "Show subcategory list above topics in this category." show_subcategory_list: "Show subcategory list above topics in this category."
num_featured_topics: "Number of topics shown on the categories page:" num_featured_topics: "Number of topics shown on the categories page:"
subcategory_num_featured_topics: "Number of featured topics on parent category's page:" subcategory_num_featured_topics: "Number of featured topics on parent category's page:"

View File

@ -28,8 +28,8 @@ end
ColumnDropper.drop( ColumnDropper.drop(
table: 'categories', table: 'categories',
after_migration: 'AddUploadsToCategories', after_migration: 'AddSuppressFromLatestToCategories',
columns: ['logo_url', 'background_url'], columns: ['logo_url', 'background_url', 'suppress_from_homepage'],
on_drop: ->() { on_drop: ->() {
STDERR.puts 'Removing superflous categories columns!' STDERR.puts 'Removing superflous categories columns!'
} }

View File

@ -0,0 +1,11 @@
class AddSuppressFromLatestToCategories < ActiveRecord::Migration[5.1]
def up
add_column :categories, :suppress_from_latest, :boolean, default: false
execute <<~SQL
UPDATE categories SET suppress_from_latest = suppress_from_homepage
SQL
end
def down
raise "can not be removed"
end
end

View File

@ -5,7 +5,7 @@ module ImportExport
CATEGORY_ATTRS = [:id, :name, :color, :created_at, :user_id, :slug, :description, :text_color, CATEGORY_ATTRS = [:id, :name, :color, :created_at, :user_id, :slug, :description, :text_color,
:auto_close_hours, :parent_category_id, :auto_close_based_on_last_post, :auto_close_hours, :parent_category_id, :auto_close_based_on_last_post,
:topic_template, :suppress_from_homepage, :all_topics_wiki, :permissions_params] :topic_template, :suppress_from_latest, :all_topics_wiki, :permissions_params]
GROUP_ATTRS = [ :id, :name, :created_at, :mentionable_level, :messageable_level, :visibility_level, GROUP_ATTRS = [ :id, :name, :created_at, :mentionable_level, :messageable_level, :visibility_level,
:automatic_membership_email_domains, :automatic_membership_retroactive, :automatic_membership_email_domains, :automatic_membership_retroactive,

View File

@ -273,7 +273,7 @@ class ImportScripts::DiscuzX < ImportScripts::Base
description: row['description'], description: row['description'],
position: row['position'].to_i + max_position, position: row['position'].to_i + max_position,
color: color, color: color,
suppress_from_homepage: (row['status'] == (0) || row['status'] == (3)), suppress_from_latest: (row['status'] == (0) || row['status'] == (3)),
post_create_action: lambda do |category| post_create_action: lambda do |category|
if slug = @category_slug[row['id']] if slug = @category_slug[row['id']]
category.update(slug: slug) category.update(slug: slug)

View File

@ -364,13 +364,13 @@ describe ListController do
describe "categories suppression" do describe "categories suppression" do
let(:category_one) { Fabricate(:category) } let(:category_one) { Fabricate(:category) }
let(:sub_category) { Fabricate(:category, parent_category: category_one, suppress_from_homepage: true) } let(:sub_category) { Fabricate(:category, parent_category: category_one, suppress_from_latest: true) }
let!(:topic_in_sub_category) { Fabricate(:topic, category: sub_category) } let!(:topic_in_sub_category) { Fabricate(:topic, category: sub_category) }
let(:category_two) { Fabricate(:category, suppress_from_homepage: true) } let(:category_two) { Fabricate(:category, suppress_from_latest: true) }
let!(:topic_in_category_two) { Fabricate(:topic, category: category_two) } let!(:topic_in_category_two) { Fabricate(:topic, category: category_two) }
it "suppresses categories from the homepage" do it "suppresses categories from the latest list" do
get SiteSetting.homepage, format: :json get SiteSetting.homepage, format: :json
expect(response).to be_success expect(response).to be_success

View File

@ -4,12 +4,12 @@
{"id":42,"name":"custom_group_import","created_at":"2017-10-26T15:33:46.328Z","mentionable_level":0,"messageable_level":0,"visibility_level":0,"automatic_membership_email_domains":"","automatic_membership_retroactive":false,"primary_group":false,"title":null,"grant_trust_level":null,"incoming_email":null,"user_ids":[2]} {"id":42,"name":"custom_group_import","created_at":"2017-10-26T15:33:46.328Z","mentionable_level":0,"messageable_level":0,"visibility_level":0,"automatic_membership_email_domains":"","automatic_membership_retroactive":false,"primary_group":false,"title":null,"grant_trust_level":null,"incoming_email":null,"user_ids":[2]}
], ],
"categories":[ "categories":[
{"id":8,"name":"Custom Category","color":"AB9364","created_at":"2017-10-26T15:32:44.083Z","user_id":1,"slug":"custom-category","description":null,"text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":3,"auto_close_based_on_last_post":false,"topic_template":"","suppress_from_homepage":false,"all_topics_wiki":false,"permissions_params":{"custom_group":1,"everyone":2}}, {"id":8,"name":"Custom Category","color":"AB9364","created_at":"2017-10-26T15:32:44.083Z","user_id":1,"slug":"custom-category","description":null,"text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":3,"auto_close_based_on_last_post":false,"topic_template":"","suppress_from_latest":false,"all_topics_wiki":false,"permissions_params":{"custom_group":1,"everyone":2}},
{"id":10,"name":"Site Feedback Import","color":"808281","created_at":"2017-10-26T17:12:39.995Z","user_id":-1,"slug":"site-feedback-import","description":"Discussion about this site, its organization, how it works, and how we can improve it.","text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_homepage":false,"all_topics_wiki":false,"permissions_params":{}}, {"id":10,"name":"Site Feedback Import","color":"808281","created_at":"2017-10-26T17:12:39.995Z","user_id":-1,"slug":"site-feedback-import","description":"Discussion about this site, its organization, how it works, and how we can improve it.","text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_latest":false,"all_topics_wiki":false,"permissions_params":{}},
{"id":11,"name":"Uncategorized Import","color":"AB9364","created_at":"2017-10-26T17:12:32.359Z","user_id":-1,"slug":"uncategorized-import","description":"","text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_homepage":false,"all_topics_wiki":false,"permissions_params":{}}, {"id":11,"name":"Uncategorized Import","color":"AB9364","created_at":"2017-10-26T17:12:32.359Z","user_id":-1,"slug":"uncategorized-import","description":"","text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_latest":false,"all_topics_wiki":false,"permissions_params":{}},
{"id":12,"name":"Lounge Import","color":"EEEEEE","created_at":"2017-10-26T17:12:39.490Z","user_id":-1,"slug":"lounge-import","description":"A category exclusive to members with trust level 3 and higher.","text_color":"652D90","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_homepage":false,"all_topics_wiki":false,"permissions_params":{"trust_level_3":1}}, {"id":12,"name":"Lounge Import","color":"EEEEEE","created_at":"2017-10-26T17:12:39.490Z","user_id":-1,"slug":"lounge-import","description":"A category exclusive to members with trust level 3 and higher.","text_color":"652D90","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_latest":false,"all_topics_wiki":false,"permissions_params":{"trust_level_3":1}},
{"id":13,"name":"Staff Import","color":"283890","created_at":"2017-10-26T17:12:42.806Z","user_id":2,"slug":"staff-import","description":"Private category for staff discussions. Topics are only visible to admins and moderators.","text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_homepage":false,"all_topics_wiki":false,"permissions_params":{"custom_group_import":1,"staff":1}}, {"id":13,"name":"Staff Import","color":"283890","created_at":"2017-10-26T17:12:42.806Z","user_id":2,"slug":"staff-import","description":"Private category for staff discussions. Topics are only visible to admins and moderators.","text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":null,"auto_close_based_on_last_post":false,"topic_template":null,"suppress_from_latest":false,"all_topics_wiki":false,"permissions_params":{"custom_group_import":1,"staff":1}},
{"id":15,"name":"Custom Category Import","color":"AB9364","created_at":"2017-10-26T15:32:44.083Z","user_id":2,"slug":"custom-category-import","description":null,"text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":10,"auto_close_based_on_last_post":false,"topic_template":"","suppress_from_homepage":false,"all_topics_wiki":false,"permissions_params":{"custom_group_import":1,"everyone":2}} {"id":15,"name":"Custom Category Import","color":"AB9364","created_at":"2017-10-26T15:32:44.083Z","user_id":2,"slug":"custom-category-import","description":null,"text_color":"FFFFFF","auto_close_hours":null,"parent_category_id":10,"auto_close_based_on_last_post":false,"topic_template":"","suppress_from_latest":false,"all_topics_wiki":false,"permissions_params":{"custom_group_import":1,"everyone":2}}
], ],
"users":[ "users":[
{"id":1,"email":"email@example.com","username":"example","name":"Example","created_at":"2017-10-07T15:01:24.597Z","trust_level":4,"active":true,"last_emailed_at":null}, {"id":1,"email":"email@example.com","username":"example","name":"Example","created_at":"2017-10-07T15:01:24.597Z","trust_level":4,"active":true,"last_emailed_at":null},

View File

@ -15,6 +15,33 @@ RSpec.describe ListController do
end end
end end
describe 'suppress from latest' do
it 'supresses categories' do
topic
get "/latest.json"
data = JSON.parse(response.body)
expect(data["topic_list"]["topics"].length).to eq(1)
get "/categories_and_latest.json"
data = JSON.parse(response.body)
expect(data["topic_list"]["topics"].length).to eq(1)
topic.category.suppress_from_latest = true
topic.category.save
get "/latest.json"
data = JSON.parse(response.body)
expect(data["topic_list"]["topics"].length).to eq(0)
get "/categories_and_latest.json"
data = JSON.parse(response.body)
expect(data["topic_list"]["topics"].length).to eq(0)
end
end
describe 'titles for crawler layout' do describe 'titles for crawler layout' do
it 'has no title for the default URL' do it 'has no title for the default URL' do
topic topic