DEV: Ensure banned phrases do not occur in en translations (#30264)

This will help us keep consistency with things that we've decided to rename. Initial rules are for "color scheme" -> "color palette", and "private message" -> "personal message".

Also updates some remaining occurences of "color scheme" in our translation files.

Co-authored-by: Gerhard Schlager <gerhard.schlager@discourse.org>
This commit is contained in:
David Taylor 2024-12-13 16:02:32 +00:00 committed by GitHub
parent f6a4de4805
commit 78dacf773a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 16 deletions

View File

@ -1347,18 +1347,18 @@ en:
description: "Skip new user onboarding tips and badges" description: "Skip new user onboarding tips and badges"
reset_seen_user_tips: "Show user tips again" reset_seen_user_tips: "Show user tips again"
theme_default_on_all_devices: "Make this the default theme on all my devices" theme_default_on_all_devices: "Make this the default theme on all my devices"
color_scheme_default_on_all_devices: "Set default color scheme on all my devices" color_scheme_default_on_all_devices: "Set default color palette on all my devices"
color_scheme: "Color Scheme" color_scheme: "Color Palette"
color_schemes: color_schemes:
default_description: "Theme default" default_description: "Theme default"
disable_dark_scheme: "Same as regular" disable_dark_scheme: "Same as regular"
dark_instructions: "You can preview the dark mode color scheme by toggling your device's dark mode." dark_instructions: "You can preview the dark mode color palette by toggling your device's dark mode."
undo: "Reset" undo: "Reset"
regular: "Regular" regular: "Regular"
dark: "Dark mode" dark: "Dark mode"
default_dark_scheme: "(site default)" default_dark_scheme: "(site default)"
dark_mode: "Dark Mode" dark_mode: "Dark Mode"
dark_mode_enable: "Enable automatic dark mode color scheme" dark_mode_enable: "Enable automatic dark mode color palette"
text_size_default_on_all_devices: "Make this the default text size on all my devices" text_size_default_on_all_devices: "Make this the default text size on all my devices"
allow_private_messages: "Allow other users to send me personal messages" allow_private_messages: "Allow other users to send me personal messages"
external_links_in_new_tab: "Open all external links in a new tab" external_links_in_new_tab: "Open all external links in a new tab"
@ -5598,7 +5598,7 @@ en:
sidebar_link: sidebar_link:
font_style: "Font Style" font_style: "Font Style"
site_logo: "Site Logo" site_logo: "Site Logo"
color_schemes: "Color Schemes" color_schemes: "Color Palettes"
emoji: "Emoji" emoji: "Emoji"
navigation: "Navigation" navigation: "Navigation"
themes: "Themes" themes: "Themes"
@ -5962,7 +5962,7 @@ en:
hide_unused_fields: "Hide unused fields" hide_unused_fields: "Hide unused fields"
is_default: "Theme is enabled by default" is_default: "Theme is enabled by default"
user_selectable: "Theme can be selected by users" user_selectable: "Theme can be selected by users"
color_scheme_user_selectable: "Color scheme can be selected by users" color_scheme_user_selectable: "Color palette can be selected by users"
auto_update: "Auto update when Discourse is updated" auto_update: "Auto update when Discourse is updated"
color_scheme: "Color Palette" color_scheme: "Color Palette"
edit_color_scheme: "Edit Color Palette" edit_color_scheme: "Edit Color Palette"

View File

@ -2239,7 +2239,7 @@ en:
desktop_category_page_style: "This setting determines the visual layout of the /categories page on desktop. It includes options such as displaying subcategories with featured topics, showing the latest topics, or presenting top topics. The chosen style will influence how users interact and navigate through categories on the site." desktop_category_page_style: "This setting determines the visual layout of the /categories page on desktop. It includes options such as displaying subcategories with featured topics, showing the latest topics, or presenting top topics. The chosen style will influence how users interact and navigate through categories on the site."
category_colors: "A list of hexadecimal color values allowed for categories." category_colors: "A list of hexadecimal color values allowed for categories."
default_dark_mode_color_scheme_id: "The color scheme used when in dark mode." default_dark_mode_color_scheme_id: "The color palette used when in dark mode."
dark_mode_none: "None" dark_mode_none: "None"
max_image_size_kb: "The maximum image upload size. This must be configured in nginx (client_max_body_size) / apache or proxy as well. Images larger than this and smaller than client_max_body_size will be resized to fit on upload." max_image_size_kb: "The maximum image upload size. This must be configured in nginx (client_max_body_size) / apache or proxy as well. Images larger than this and smaller than client_max_body_size will be resized to fit on upload."
@ -5412,7 +5412,7 @@ en:
title: "Look and feel" title: "Look and feel"
fields: fields:
color_scheme: color_scheme:
label: "Color scheme" label: "Color palette"
body_font: body_font:
label: "Body font" label: "Body font"
heading_font: heading_font:

View File

@ -26,6 +26,9 @@ class I18nLinter
end end
class LocaleFileValidator class LocaleFileValidator
# Format: "banned phrase" => "recommendation"
BANNED_PHRASES = { "color scheme" => "color palette", "private message" => "personal message" }
ERROR_MESSAGES = { ERROR_MESSAGES = {
invalid_relative_links: invalid_relative_links:
"The following keys have relative links, but do not start with %{base_url} or %{base_path}:", "The following keys have relative links, but do not start with %{base_url} or %{base_path}:",
@ -37,7 +40,16 @@ class LocaleFileValidator
"Pluralized strings must have only the sub-keys 'one' and 'other'.\nThe following keys have missing or additional keys:", "Pluralized strings must have only the sub-keys 'one' and 'other'.\nThe following keys have missing or additional keys:",
invalid_one_keys: invalid_one_keys:
"The following keys contain the number 1 instead of the interpolation key %{count}:", "The following keys contain the number 1 instead of the interpolation key %{count}:",
} }.merge(
BANNED_PHRASES
.map do |banned, recommendation|
[
"banned_phrase_#{banned}",
"The following keys contain the banned phrase '#{banned}' (use '#{recommendation}' instead)",
]
end
.to_h,
)
PLURALIZATION_KEYS = %w[zero one two few many other] PLURALIZATION_KEYS = %w[zero one two few many other]
ENGLISH_KEYS = %w[one other] ENGLISH_KEYS = %w[one other]
@ -49,6 +61,7 @@ class LocaleFileValidator
def initialize(filename) def initialize(filename)
@filename = filename @filename = filename
@errors = {} @errors = {}
ERROR_MESSAGES.keys.each { |type| @errors[type] = [] }
end end
def has_errors? def has_errors?
@ -87,10 +100,6 @@ class LocaleFileValidator
end end
def validate_content(yaml) def validate_content(yaml)
@errors[:invalid_relative_links] = []
@errors[:invalid_relative_image_sources] = []
@errors[:invalid_interpolation_key_format] = []
each_translation(yaml) do |key, value| each_translation(yaml) do |key, value|
@errors[:invalid_relative_links] << key if value.match?(%r{href\s*=\s*["']/[^/]|\]\(/[^/]}i) @errors[:invalid_relative_links] << key if value.match?(%r{href\s*=\s*["']/[^/]|\]\(/[^/]}i)
@ -100,6 +109,10 @@ class LocaleFileValidator
!EXEMPTED_DOUBLE_CURLY_BRACKET_KEYS.include?(key) !EXEMPTED_DOUBLE_CURLY_BRACKET_KEYS.include?(key)
@errors[:invalid_interpolation_key_format] << key @errors[:invalid_interpolation_key_format] << key
end end
BANNED_PHRASES.keys.each do |banned|
@errors["banned_phrase_#{banned}"] << key if value.include?(banned)
end
end end
end end
@ -115,9 +128,6 @@ class LocaleFileValidator
end end
def validate_pluralizations(yaml) def validate_pluralizations(yaml)
@errors[:wrong_pluralization_keys] = []
@errors[:invalid_one_keys] = []
each_pluralization(yaml) do |key, hash| each_pluralization(yaml) do |key, hash|
# ignore errors from some ActiveRecord messages # ignore errors from some ActiveRecord messages
next if key.include?("messages.restrict_dependent_destroy") next if key.include?("messages.restrict_dependent_destroy")