UX: Introduce automatic 'categories topics' setting (#8804)
When 'categories topics' setting is set to 0, the system will automatically try to find a value to keep the two columns (categories and topics) symmetrical. The value is computed as 1.5x the number of top level categories and at least 5 topics will always be returned.
This commit is contained in:
parent
d24d47b2ee
commit
09e8be3209
|
@ -8,6 +8,9 @@ class CategoriesController < ApplicationController
|
|||
before_action :initialize_staff_action_logger, only: [:create, :update, :destroy]
|
||||
skip_before_action :check_xhr, only: [:index, :categories_and_latest, :categories_and_top, :redirect]
|
||||
|
||||
SYMMETRICAL_CATEGORIES_TO_TOPICS_FACTOR = 1.5
|
||||
MIN_CATEGORIES_TOPICS = 5
|
||||
|
||||
def redirect
|
||||
return if handle_permalink("/category/#{params[:path]}")
|
||||
redirect_to path("/c/#{params[:path]}")
|
||||
|
@ -46,7 +49,7 @@ class CategoriesController < ApplicationController
|
|||
|
||||
style = SiteSetting.desktop_category_page_style
|
||||
topic_options = {
|
||||
per_page: SiteSetting.categories_topics,
|
||||
per_page: CategoriesController.topics_per_page,
|
||||
no_definitions: true
|
||||
}
|
||||
|
||||
|
@ -226,6 +229,15 @@ class CategoriesController < ApplicationController
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def self.topics_per_page
|
||||
return SiteSetting.categories_topics if SiteSetting.categories_topics > 0
|
||||
|
||||
count = Category.where(parent_category: nil).count
|
||||
count = (SYMMETRICAL_CATEGORIES_TO_TOPICS_FACTOR * count).to_i
|
||||
count > MIN_CATEGORIES_TOPICS ? count : MIN_CATEGORIES_TOPICS
|
||||
end
|
||||
|
||||
def categories_and_topics(topics_filter)
|
||||
discourse_expires_in 1.minute
|
||||
|
||||
|
@ -236,7 +248,7 @@ class CategoriesController < ApplicationController
|
|||
}
|
||||
|
||||
topic_options = {
|
||||
per_page: SiteSetting.categories_topics,
|
||||
per_page: CategoriesController.topics_per_page,
|
||||
no_definitions: true
|
||||
}
|
||||
|
||||
|
|
|
@ -1686,7 +1686,7 @@ en:
|
|||
alert_admins_if_errors_per_minute: "Number of errors per minute in order to trigger an admin alert. A value of 0 disables this feature. NOTE: requires restart."
|
||||
alert_admins_if_errors_per_hour: "Number of errors per hour in order to trigger an admin alert. A value of 0 disables this feature. NOTE: requires restart."
|
||||
|
||||
categories_topics: "Number of topics to show in /categories page."
|
||||
categories_topics: "Number of topics to show in /categories page. If set to 0, it will automatically try to find a value to keep the two columns symmetrical (categories and topics)."
|
||||
suggested_topics: "Number of suggested topics shown at the bottom of a topic."
|
||||
limit_suggested_to_category: "Only show topics from the current category in suggested topics."
|
||||
suggested_topics_max_days_old: "Suggested topics should not be more than n days old."
|
||||
|
|
|
@ -135,8 +135,7 @@ basic:
|
|||
default: false
|
||||
categories_topics:
|
||||
default: 20
|
||||
min: 5
|
||||
max: 2000
|
||||
validator: "CategoriesTopicsValidator"
|
||||
suggested_topics:
|
||||
client: true
|
||||
default: 5
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CategoriesTopicsValidator
|
||||
def initialize(opts = {})
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
def valid_value?(val)
|
||||
num = val.to_i
|
||||
return false if num.to_s != val.to_s
|
||||
return false if num != 0 && num < CategoriesController::MIN_CATEGORIES_TOPICS
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def error_message
|
||||
I18n.t('site_settings.errors.invalid_integer_min', min: 5)
|
||||
end
|
||||
end
|
|
@ -481,4 +481,41 @@ describe CategoriesController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '#categories_and_topics' do
|
||||
before do
|
||||
10.times.each { Fabricate(:topic) }
|
||||
end
|
||||
|
||||
it 'works when SiteSetting.categories_topics is non-null' do
|
||||
SiteSetting.categories_topics = 5
|
||||
|
||||
get '/categories_and_latest.json'
|
||||
expect(JSON.parse(response.body)['topic_list']['topics'].size).to eq(5)
|
||||
end
|
||||
|
||||
it 'works when SiteSetting.categories_topics is null' do
|
||||
SiteSetting.categories_topics = 0
|
||||
|
||||
get '/categories_and_latest.json'
|
||||
json = JSON.parse(response.body)
|
||||
expect(json['category_list']['categories'].size).to eq(2) # 'Uncategorized' and category
|
||||
expect(json['topic_list']['topics'].size).to eq(5)
|
||||
|
||||
Fabricate(:category, parent_category: category)
|
||||
|
||||
get '/categories_and_latest.json'
|
||||
json = JSON.parse(response.body)
|
||||
expect(json['category_list']['categories'].size).to eq(2)
|
||||
expect(json['topic_list']['topics'].size).to eq(5)
|
||||
|
||||
Fabricate(:category)
|
||||
Fabricate(:category)
|
||||
|
||||
get '/categories_and_latest.json'
|
||||
json = JSON.parse(response.body)
|
||||
expect(json['category_list']['categories'].size).to eq(4)
|
||||
expect(json['topic_list']['topics'].size).to eq(6)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue