From 5bc73711927005513a151d9d4a42c27d42404055 Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Fri, 31 Jan 2025 12:55:30 +1000 Subject: [PATCH] FEATURE: Localization admin settings config page (#31085) This commit adds a new Localization config page for admins, as a basic filtered site setting page similar to Legal and Notifications. Included settings are: * default locale * allow user locale * set locale from accept langauge header * onebox locale * display local time in user card * discourse local dates enabled * support mixed text direction * unicode usernames * allowed unicode username characters --- .../admin-config-localization-settings.js | 3 ++ .../addon/routes/admin-config-localization.js | 8 +++++ .../admin/addon/routes/admin-route-map.js | 5 +++ .../config-localization-settings.gjs | 31 +++++++++++++++++++ .../app/lib/sidebar/admin-nav-map.js | 6 ++++ .../admin/config/site_settings_controller.rb | 2 +- app/models/site_setting.rb | 1 + config/locales/client.en.yml | 6 ++++ config/locales/server.en.yml | 10 +++--- config/routes.rb | 1 + config/site_settings.yml | 9 ++++++ .../config/locales/server.en.yml | 4 +-- .../discourse-local-dates/config/settings.yml | 1 + 13 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 app/assets/javascripts/admin/addon/controllers/admin-config-localization-settings.js create mode 100644 app/assets/javascripts/admin/addon/routes/admin-config-localization.js create mode 100644 app/assets/javascripts/admin/addon/templates/config-localization-settings.gjs diff --git a/app/assets/javascripts/admin/addon/controllers/admin-config-localization-settings.js b/app/assets/javascripts/admin/addon/controllers/admin-config-localization-settings.js new file mode 100644 index 00000000000..9fca30b4d2a --- /dev/null +++ b/app/assets/javascripts/admin/addon/controllers/admin-config-localization-settings.js @@ -0,0 +1,3 @@ +import AdminAreaSettingsBaseController from "admin/controllers/admin-area-settings-base"; + +export default class AdminConfigLocalizationSettingsController extends AdminAreaSettingsBaseController {} diff --git a/app/assets/javascripts/admin/addon/routes/admin-config-localization.js b/app/assets/javascripts/admin/addon/routes/admin-config-localization.js new file mode 100644 index 00000000000..1c942db0f26 --- /dev/null +++ b/app/assets/javascripts/admin/addon/routes/admin-config-localization.js @@ -0,0 +1,8 @@ +import DiscourseRoute from "discourse/routes/discourse"; +import { i18n } from "discourse-i18n"; + +export default class AdminConfigLocalizationRoute extends DiscourseRoute { + titleToken() { + return i18n("admin.community.sidebar_link.localization.title"); + } +} diff --git a/app/assets/javascripts/admin/addon/routes/admin-route-map.js b/app/assets/javascripts/admin/addon/routes/admin-route-map.js index d96d0f75118..9742b856d10 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-route-map.js +++ b/app/assets/javascripts/admin/addon/routes/admin-route-map.js @@ -227,6 +227,11 @@ export default function () { }); } ); + this.route("localization", function () { + this.route("settings", { + path: "/", + }); + }); this.route("notifications", function () { this.route("settings", { path: "/", diff --git a/app/assets/javascripts/admin/addon/templates/config-localization-settings.gjs b/app/assets/javascripts/admin/addon/templates/config-localization-settings.gjs new file mode 100644 index 00000000000..093091f2be2 --- /dev/null +++ b/app/assets/javascripts/admin/addon/templates/config-localization-settings.gjs @@ -0,0 +1,31 @@ +import RouteTemplate from "ember-route-template"; +import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item"; +import DPageHeader from "discourse/components/d-page-header"; +import { i18n } from "discourse-i18n"; +import AdminAreaSettings from "admin/components/admin-area-settings"; + +export default RouteTemplate(); diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/admin-nav-map.js b/app/assets/javascripts/discourse/app/lib/sidebar/admin-nav-map.js index 26a6886efa1..1363203ff2e 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/admin-nav-map.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/admin-nav-map.js @@ -52,6 +52,12 @@ export const ADMIN_NAV_MAP = [ label: "admin.community.sidebar_link.notifications", icon: "bell", }, + { + name: "admin_localization", + route: "adminConfig.localization.settings", + label: "admin.community.sidebar_link.localization.title", + icon: "globe", + }, { name: "admin_permalinks", route: "adminPermalinks", diff --git a/app/controllers/admin/config/site_settings_controller.rb b/app/controllers/admin/config/site_settings_controller.rb index 1d9499a8831..352c5f06616 100644 --- a/app/controllers/admin/config/site_settings_controller.rb +++ b/app/controllers/admin/config/site_settings_controller.rb @@ -24,7 +24,7 @@ class Admin::Config::SiteSettingsController < Admin::AdminController filter_area: params[:filter_area], filter_plugin: params[:plugin], filter_categories: Array.wrap(params[:categories]), - include_locale_setting: false, + include_locale_setting: params[:filter_area] == "localization", include_hidden: true, filter_allowed_hidden: ADMIN_CONFIG_AREA_ALLOWLISTED_HIDDEN_SETTINGS, ), diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 473881b973c..62d2773aac3 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -9,6 +9,7 @@ class SiteSetting < ActiveRecord::Base fonts group_permissions legal + localization navigation notifications permalinks diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 5fec7000495..50aca853eea 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -5154,6 +5154,9 @@ en: legal: title: "Legal" header_description: "Configure legal settings, such as terms of service, privacy policy, contact details, and EU-specific considerations" + localization: + title: "Localization" + header_description: "Configure your community’s interface language and other localization options for your members" login_and_authentication: title: "Login & authentication" header_description: "Configure how users log in and authenticate, secrets and keys, OAuth2 providers, and more" @@ -5692,6 +5695,9 @@ en: group_permissions: "Group permissions" users: "Users" groups: "Groups" + localization: + title: "Localization" + keywords: "locale|language|timezone|unicode|ltr" user_fields: "User fields" watched_words: "Watched words" legal: "Legal" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index dcc22bd815e..1b178612d99 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1735,10 +1735,10 @@ en: delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days." default_locale: "The default language of this Discourse instance. You can replace the text of system generated categories and topics at Customize / Text." allow_user_locale: "Allow users to choose their own language interface preference" - set_locale_from_accept_language_header: "set interface language for anonymous users from their web browser's language headers" + set_locale_from_accept_language_header: "Set interface language for anonymous users from their web browser's language headers" set_locale_from_cookie: "Allows setting an anonymous user's locale via the 'locale' browser cookie" set_locale_from_param: "Allows setting an anonymous user's locale via the 'lang' URL param, e.g. ?lang=es" - support_mixed_text_direction: "Support mixed left-to-right and right-to-left text directions." + support_mixed_text_direction: "Support mixed left-to-right and right-to-left text directions" min_post_length: "Minimum allowed post length in characters (excluding personal messages)" min_first_post_length: "Minimum allowed first post (topic body) length (excluding personal messages)" min_personal_message_post_length: "Minimum allowed post length in characters for messages (both first post and replies)" @@ -1808,7 +1808,7 @@ en: block_onebox_on_redirect: "Prevent oneboxing for URLs that lead to a redirecting page. This configuration stops the creation of a visual card (onebox) for any URL that redirects to a different destination, ensuring that direct, non-redirecting URLs are prioritized for oneboxing." allowed_inline_onebox_domains: "A list of domains that will be oneboxed in miniature form if linked without a title" enable_inline_onebox_on_all_domains: "Ignore allowed_inline_onebox_domains site setting and allow inline onebox on all domains." - onebox_locale: "The locale sent to onebox providers. If left blank, the default locale will be used." + onebox_locale: "The locale sent to onebox providers. If left blank, the default locale will be used" force_custom_user_agent_hosts: "Hosts for which to use the custom onebox user agent on all requests. (Especially useful for hosts that limit access by user agent)." max_oneboxes_per_post: "Set the maximum number of oneboxes that can be included in a single post. Oneboxes provide a preview of linked content within the post." facebook_app_access_token: "A token generated from your Facebook app ID and secret. Used to generate Instagram oneboxes." @@ -1974,8 +1974,8 @@ en: min_username_length: "Minimum username length in characters. WARNING: if any existing users or groups have names shorter than this, your site will break!" max_username_length: "Maximum username length in characters. WARNING: if any existing users or groups have names longer than this, your site will break!" - unicode_usernames: "Allow usernames and group names to contain Unicode letters and numbers." - allowed_unicode_username_characters: "Regular expression to allow only some Unicode characters within usernames. ASCII letters and numbers will always be allowed and don't need to be included in the allowlist." + unicode_usernames: "Allow usernames and group names to contain Unicode letters and numbers" + allowed_unicode_username_characters: "Regular expression to allow only some Unicode characters within usernames. ASCII letters and numbers will always be allowed and don't need to be included in the allowlist" reserved_usernames: "Usernames for which signup is not allowed. Wildcard symbol * can be used to match any character zero or more times." diff --git a/config/routes.rb b/config/routes.rb index 949b0c4a965..4f84e151523 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -393,6 +393,7 @@ Discourse::Application.routes.draw do get "fonts" => "site_settings#index" get "files" => "site_settings#index" get "legal" => "site_settings#index" + get "localization" => "site_settings#index" get "login-and-authentication" => "site_settings#index" get "logo" => "site_settings#index" get "navigation" => "site_settings#index" diff --git a/config/site_settings.yml b/config/site_settings.yml index da0b17869c1..3df2e7b5658 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -149,24 +149,30 @@ basic: display_local_time_in_user_card: client: true default: false + area: "localization" allow_user_locale: client: true default: false + area: "localization" set_locale_from_accept_language_header: default: false client: true validator: "AllowUserLocaleEnabledValidator" + area: "localization" set_locale_from_cookie: default: false client: true validator: "AllowUserLocaleEnabledValidator" + area: "localization" set_locale_from_param: default: false client: true validator: "AllowUserLocaleEnabledValidator" + area: "localization" support_mixed_text_direction: client: true default: false + area: "localization" categories_topics: default: 20 validator: "CategoriesTopicsValidator" @@ -697,6 +703,7 @@ users: default: false client: true validator: "UnicodeUsernameValidator" + area: "localization" allowed_unicode_username_characters: validator: "UnicodeUsernameAllowlistValidator" default: "" @@ -708,6 +715,7 @@ users: ko: '\p{Hangul}' zh_CN: '\p{Han}' zh_TW: '\p{Han}' + area: "localization" reserved_usernames: type: list list_type: compact @@ -2312,6 +2320,7 @@ onebox: default: "" type: enum enum: "OneboxLocaleSiteSetting" + area: "localization" force_custom_user_agent_hosts: default: "http://codepen.io" type: list diff --git a/plugins/discourse-local-dates/config/locales/server.en.yml b/plugins/discourse-local-dates/config/locales/server.en.yml index b1c5bc735a7..94721d5e947 100644 --- a/plugins/discourse-local-dates/config/locales/server.en.yml +++ b/plugins/discourse-local-dates/config/locales/server.en.yml @@ -1,6 +1,6 @@ en: site_settings: - discourse_local_dates_enabled: "Enable the discourse-local-dates feature. This will add support to local timezone aware dates in posts using the [date] element." + discourse_local_dates_enabled: "Enable the discourse-local-dates feature. This will add support to local timezone aware dates in posts using the [date] element" discourse_local_dates_default_formats: "Frequently used date time formats, see: momentjs string format" discourse_local_dates_default_timezones: "Default list of timezones, must be a valid TZ" - discourse_local_dates_email_format: "Format used to display a date in emails." + discourse_local_dates_email_format: "Format used to display a date in emails" diff --git a/plugins/discourse-local-dates/config/settings.yml b/plugins/discourse-local-dates/config/settings.yml index 17842807932..a4934b215a8 100644 --- a/plugins/discourse-local-dates/config/settings.yml +++ b/plugins/discourse-local-dates/config/settings.yml @@ -5,6 +5,7 @@ plugins: discourse_local_dates_enabled: default: true client: true + area: "localization" discourse_local_dates_default_formats: default: "LLL|LTS|LL|LLLL" client: true