mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 10:47:46 -05:00
FEATURE: Add locale as a filter on topic /filter (#35299)
Adds `locale` as a new filter on /filter for topics. - locale:en -- single locale filtering - locale:ja,es -- comma-separated OR logic - locale:ja locale:es -- space-separated OR logic - -locale:en -- exclusion of single locale - -locale:en,ja -- exclusion of multiple locales - locale:en status:closed -- combination with other filters
This commit is contained in:
@@ -2952,6 +2952,9 @@ en:
|
||||
group: "Filter topics by groups"
|
||||
groups_any: "Show topics with any of the specified groups (comma-separated)"
|
||||
groups_all: "Show topics with all of the specified groups (plus-separated)"
|
||||
locale: "Filter topics by original language"
|
||||
locale_any: "Show topics originally written in any of the specified languages (comma-separated)"
|
||||
exclude_locale: "Exclude topics originally written in a specific language"
|
||||
|
||||
discourse_connect:
|
||||
login_error: "Login Error"
|
||||
|
||||
@@ -87,6 +87,8 @@ class TopicsFilter
|
||||
filter_tag_groups(values: key_prefixes.zip(filter_values))
|
||||
when "tag"
|
||||
filter_tags(values: key_prefixes.zip(filter_values))
|
||||
when "locale"
|
||||
filter_locale(values: key_prefixes.zip(filter_values))
|
||||
when "views-min"
|
||||
filter_by_number_of_views(min: filter_values)
|
||||
when "views-max"
|
||||
@@ -343,6 +345,17 @@ class TopicsFilter
|
||||
},
|
||||
)
|
||||
|
||||
# Locale filter
|
||||
results.push(
|
||||
{
|
||||
name: "locale:",
|
||||
description: I18n.t("filter.description.locale"),
|
||||
type: "text",
|
||||
delimiters: [{ name: ",", description: I18n.t("filter.description.locale_any") }],
|
||||
prefixes: [{ name: "-", description: I18n.t("filter.description.exclude_locale") }],
|
||||
},
|
||||
)
|
||||
|
||||
# this modifier allows custom plugins to add UI tips in the /filter route
|
||||
DiscoursePluginRegistry.apply_modifier(:topics_filter_options, results, guardian)
|
||||
end
|
||||
@@ -902,6 +915,28 @@ class TopicsFilter
|
||||
.distinct(:id)
|
||||
end
|
||||
|
||||
def filter_locale(values:)
|
||||
include_locales = []
|
||||
exclude_locales = []
|
||||
|
||||
values.each do |key_prefix, value|
|
||||
locales = value.split(",").map(&:strip).reject(&:blank?)
|
||||
next if locales.empty?
|
||||
|
||||
if key_prefix == "-"
|
||||
exclude_locales.concat(locales)
|
||||
else
|
||||
include_locales.concat(locales)
|
||||
end
|
||||
end
|
||||
|
||||
@scope = @scope.where(locale: include_locales) if include_locales.present?
|
||||
|
||||
if exclude_locales.present?
|
||||
@scope = @scope.where("topics.locale IS NULL OR topics.locale NOT IN (?)", exclude_locales)
|
||||
end
|
||||
end
|
||||
|
||||
ORDER_BY_MAPPINGS = {
|
||||
"activity" => {
|
||||
column: "topics.bumped_at",
|
||||
|
||||
@@ -1419,6 +1419,93 @@ RSpec.describe TopicsFilter do
|
||||
).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
describe "when filtering by locale" do
|
||||
fab!(:en_topic) { Fabricate(:topic, locale: "en") }
|
||||
fab!(:ja_topic) { Fabricate(:topic, locale: "ja") }
|
||||
fab!(:es_topic) { Fabricate(:topic, locale: "es") }
|
||||
fab!(:no_locale_topic, :topic)
|
||||
|
||||
describe "when query string is `locale:en`" do
|
||||
it "should only return topics with locale en" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("locale:en")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(en_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `locale:ja,es`" do
|
||||
it "should return topics with locale ja or es" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("locale:ja,es")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(ja_topic.id, es_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `locale:ja locale:es`" do
|
||||
it "should return topics with locale ja or es" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("locale:ja locale:es")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(ja_topic.id, es_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `-locale:en`" do
|
||||
it "should return topics without locale en" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("-locale:en")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(ja_topic.id, es_topic.id, no_locale_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `-locale:en,ja`" do
|
||||
it "should return topics without locale en or ja" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("-locale:en,ja")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(es_topic.id, no_locale_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when query string is `locale:invalid`" do
|
||||
it "should return no topics" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("locale:invalid")
|
||||
.pluck(:id),
|
||||
).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
describe "when combining with other filters" do
|
||||
before { en_topic.update!(closed: true) }
|
||||
|
||||
it "should work with status:closed" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("locale:en status:closed")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(en_topic.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when filtering by topic author" do
|
||||
fab!(:user2) { Fabricate(:user, username: "username2") }
|
||||
fab!(:topic_by_user) { Fabricate(:topic, user: user) }
|
||||
|
||||
Reference in New Issue
Block a user