Skip to content

Commit

Permalink
FEATURE: English locale with international date formats
Browse files Browse the repository at this point in the history
Makes en_US the new default locale
  • Loading branch information
gschlager committed May 20, 2019
1 parent a58aa9b commit b788948
Show file tree
Hide file tree
Showing 44 changed files with 274 additions and 90 deletions.
4 changes: 2 additions & 2 deletions Dangerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ This PR doesn't match our required code formatting standards, as enforced by pre
})
end

locales_changes = git.modified_files.grep(/config\/locales/)
has_non_en_locales_changes = locales_changes.grep_v(/config\/locales\/(client|server)\.en\.yml/).any?
locales_changes = git.modified_files.grep(%r{config/locales})
has_non_en_locales_changes = locales_changes.grep_v(%r{config/locales/(?:client|server)\.(?:en|en_US)\.yml}).any?

if locales_changes.any? && has_non_en_locales_changes
fail("Please submit your non-English translation updates via [Transifex](https://www.transifex.com/discourse/discourse-org/). You can read more on how to contribute translations [here](https://meta.discourse.org/t/contribute-a-translation-to-discourse/14882).")
Expand Down
5 changes: 5 additions & 0 deletions app/assets/javascripts/locales/en_US.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//= depend_on 'client.en_US.yml'
//= require locales/i18n

<% JsLocaleHelper.reloadable_plugins(:en_US, self) %>
<%= JsLocaleHelper.output_locale(:en_US) %>
2 changes: 1 addition & 1 deletion app/assets/javascripts/wizard/test/test_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//= require_tree ./acceptance
//= require_tree ./models
//= require_tree ./components
//= require locales/en
//= require locales/en_US
//= require fake_xml_http_request
//= require route-recognizer/dist/route-recognizer
//= require pretender/pretender
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ def set_locale
locale = current_user.effective_locale
end

I18n.locale = I18n.locale_available?(locale) ? locale : :en
I18n.locale = I18n.locale_available?(locale) ? locale : SiteSettings::DefaultsProvider::DEFAULT_LOCALE
I18n.ensure_all_loaded!
end

Expand Down
2 changes: 1 addition & 1 deletion app/jobs/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def perform(*args)
RailsMultisite::ConnectionManagement.with_connection(db) do
job_instrumenter = JobInstrumenter.new(job_class: self.class, opts: opts, db: db, jid: jid)
begin
I18n.locale = SiteSetting.default_locale || "en"
I18n.locale = SiteSetting.default_locale || SiteSettings::DefaultsProvider::DEFAULT_LOCALE
I18n.ensure_all_loaded!
begin
logster_env = {}
Expand Down
7 changes: 7 additions & 0 deletions app/models/locale_site_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ def self.reset!
end
end

FALLBACKS ||= {
en_US: :en
}

def self.fallback_locale(locale)
fallback_locale = FALLBACKS[locale.to_sym]
return fallback_locale if fallback_locale

plugin_locale = DiscoursePluginRegistry.locales[locale.to_s]
plugin_locale ? plugin_locale[:fallbackLocale]&.to_sym : nil
end
Expand Down
3 changes: 1 addition & 2 deletions app/models/translation_override.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ def self.expire_cache(key)

def check_interpolation_keys
original_text = I18n.overrides_disabled do
# lookup is protected
I18n.backend.send(:lookup, self.locale, self.translation_key)
I18n.t(translation_key, locale: :en)
end

if original_text
Expand Down
31 changes: 17 additions & 14 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,31 @@ en:
millions: "{{number}}M"
dates:
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
time: "h:mm a"
time: "HH:mm"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
timeline_date: "MMM YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_no_year: "MMM D h:mm a"
long_no_year: "D MMM HH:mm"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_no_year_no_time: "MMM D"
long_no_year_no_time: "D MMM"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
full_no_year_no_time: "MMMM Do"
full_no_year_no_time: "Do MMMM"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_with_year: "MMM D, YYYY h:mm a"
long_with_year: "D MMM YYYY HH:mm"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_with_year_no_time: "MMM D, YYYY"
long_with_year_no_time: "D MMM YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
full_with_year_no_time: "MMMM Do, YYYY"
full_with_year_no_time: "D MMMM YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_with_year: "MMM D, 'YY LT"
long_date_with_year: "D MMM 'YY LT"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_without_year: "MMM D, LT"
long_date_without_year: "D MMM LT"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_with_year_without_time: "MMM D, 'YY"
long_date_with_year_without_time: "D MMM 'YY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_without_year_with_linebreak: "MMM D <br/>LT"
long_date_without_year_with_linebreak: "D MMM <br/>LT"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_with_year_with_linebreak: "MMM D, 'YY <br/>LT"
long_date_with_year_with_linebreak: "D MMM 'YY <br/>LT"

wrap_ago: "%{date} ago"

Expand Down Expand Up @@ -98,7 +98,9 @@ en:
almost_x_years:
one: "1y"
other: "%{count}y"
date_month: "MMM D"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
date_month: "D MMM"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
date_year: "MMM 'YY"
medium:
x_minutes:
Expand All @@ -110,7 +112,8 @@ en:
x_days:
one: "1 day"
other: "%{count} days"
date_year: "MMM D, 'YY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
date_year: "D MMM 'YY"
medium_with_ago:
x_minutes:
one: "1 min ago"
Expand Down
38 changes: 38 additions & 0 deletions config/locales/client.en_US.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
en_US:
js:
dates:
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
time: "h:mm a"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
timeline_date: "MMM YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_no_year: "MMM D h:mm a"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_no_year_no_time: "MMM D"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
full_no_year_no_time: "MMMM Do"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_with_year: "MMM D, YYYY h:mm a"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_with_year_no_time: "MMM D, YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
full_with_year_no_time: "MMMM Do, YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_with_year: "MMM D, 'YY LT"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_without_year: "MMM D, LT"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_with_year_without_time: "MMM D, 'YY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_without_year_with_linebreak: "MMM D <br/>LT"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date_with_year_with_linebreak: "MMM D, 'YY <br/>LT"

tiny:
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
date_month: "MMM D"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
date_year: "MMM 'YY"
medium:
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
date_year: "MMM D, 'YY"
3 changes: 3 additions & 0 deletions config/locales/names.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ el:
en:
name: English
nativeName: English
en_US:
name: English (United States)
nativeName: English (United States)
eo:
name: Esperanto
nativeName: Esperanto
Expand Down
23 changes: 12 additions & 11 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ en:
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
short_date_no_year: "D MMM"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
short_date: "D MMM, YYYY"
short_date: "D MMM YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date: "MMMM D, YYYY h:mma"
long_date: "D MMMM YYYY LT"

datetime_formats: &datetime_formats
formats:
# Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime
short: "%m-%d-%Y"
# Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime
short_no_year: "%B %-d"
# Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime
date_only: "%B %-d, %Y"
# Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime
long: "%B %-d, %Y, %l:%M%P"
# Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
short: "%d-%m-%Y"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
short_no_year: "%-d %B"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
date_only: "%-d %B %Y"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
long: "%-d %B %Y %H:%M"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
no_day: "%B %Y"
date:
# Do not remove the brackets and commas and do not translate the first month name. It should be "null".
Expand Down Expand Up @@ -1710,6 +1710,7 @@ en:
max_image_megapixels: "Maximum number of megapixels allowed for an image."

title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc."
title_remove_extraneous_space: "Remove leading whitespaces in front of the end punctiation."

topic_views_heat_low: "After this many views, the views field is slightly highlighted."
topic_views_heat_medium: "After this many views, the views field is moderately highlighted."
Expand Down
25 changes: 25 additions & 0 deletions config/locales/server.en_US.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
en_US:
dates:
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
short_date_no_year: "D MMM"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
short_date: "D MMM, YYYY"
# Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/
long_date: "MMMM D, YYYY h:mma"

datetime_formats: &datetime_formats
formats:
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
short: "%m-%d-%Y"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
short_no_year: "%B %-d"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
date_only: "%B %-d, %Y"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
long: "%B %-d, %Y, %l:%M%P"
# Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime
no_day: "%B %Y"
date:
<<: *datetime_formats
time:
<<: *datetime_formats
5 changes: 5 additions & 0 deletions config/site_settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,11 @@ posting:
ja: false
zh_CN: false
zh_TW: false
title_remove_extraneous_space:
default: false
locale_default:
en: true
en_US: true
title_fancy_entities: true
min_personal_message_title_length:
client: true
Expand Down
55 changes: 55 additions & 0 deletions db/migrate/20190430135846_migrate_english_locale.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

class MigrateEnglishLocale < ActiveRecord::Migration[5.2]
def up
execute <<~SQL
UPDATE users
SET locale = 'en_US'
WHERE locale = 'en'
SQL

execute <<~SQL
UPDATE site_settings
SET value = 'en_US'
WHERE name = 'default_locale' AND value = 'en'
SQL

execute <<~SQL
UPDATE translation_overrides
SET locale = 'en_US'
WHERE locale = 'en'
SQL

execute <<~SQL
UPDATE theme_translation_overrides
SET locale = 'en_US'
WHERE locale = 'en'
SQL
end

def down
execute <<~SQL
UPDATE users
SET locale = 'en'
WHERE locale = 'en_US'
SQL

execute <<~SQL
UPDATE site_settings
SET value = 'en'
WHERE name = 'default_locale' AND value = 'en_US'
SQL

execute <<~SQL
UPDATE translation_overrides
SET locale = 'en'
WHERE locale = 'en_US'
SQL

execute <<~SQL
UPDATE theme_translation_overrides
SET locale = 'en'
WHERE locale = 'en_US'
SQL
end
end
29 changes: 22 additions & 7 deletions lib/js_locale_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ def self.output_locale(locale)
fallback_locale_str = LocaleSiteSetting.fallback_locale(locale_str)&.to_s
translations = Marshal.load(Marshal.dump(translations_for(locale_str)))

message_formats = strip_out_message_formats!(translations[locale_str]['js'])
message_formats.merge!(strip_out_message_formats!(translations[locale_str]['admin_js']))
message_formats = remove_message_formats!(translations, locale)
mf_locale, mf_filename = find_message_format_locale([locale_str], fallback_to_english: true)
result = generate_message_format(message_formats, mf_locale, mf_filename)

Expand All @@ -155,7 +154,8 @@ def self.output_locale(locale)
end

MOMENT_LOCALE_MAPPING ||= {
"hy" => "hy-am"
"hy" => "hy-am",
"en" => "en-gb"
}

def self.find_moment_locale(locale_chain, timezone_names: false)
Expand Down Expand Up @@ -259,18 +259,33 @@ def self.compile_message_format(path, locale, format)
"function(){ return #{message.inspect};}"
end

def self.strip_out_message_formats!(hash, prefix = "", rval = {})
def self.remove_message_formats!(translations, locale)
message_formats = {}
I18n.fallbacks[locale].map(&:to_s).each do |l|
next unless translations.key?(l)

%w{js admin_js}.each do |k|
message_formats.merge!(strip_out_message_formats!(translations[l][k]))
end
end
message_formats
end

def self.strip_out_message_formats!(hash, prefix = "", message_formats = {})
if hash.is_a?(Hash)
hash.each do |key, value|
if value.is_a?(Hash)
rval.merge!(strip_out_message_formats!(value, prefix + (prefix.length > 0 ? "." : "") << key, rval))
message_formats.merge!(strip_out_message_formats!(value, join_key(prefix, key), message_formats))
elsif key.to_s.end_with?("_MF")
rval[prefix + (prefix.length > 0 ? "." : "") << key] = value
message_formats[join_key(prefix, key)] = value
hash.delete(key)
end
end
end
rval
message_formats
end

def self.join_key(prefix, key)
prefix.blank? ? key : "#{prefix}.#{key}"
end
end
2 changes: 1 addition & 1 deletion lib/site_settings/defaults_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module SiteSettings; end

# A cache for providing default value based on site locale
class SiteSettings::DefaultsProvider
DEFAULT_LOCALE = 'en'
DEFAULT_LOCALE = 'en_US'

def initialize(site_setting)
@site_setting = site_setting
Expand Down
2 changes: 1 addition & 1 deletion lib/text_cleaner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def self.title_options
replace_all_upper_case: SiteSetting.title_prettify && !SiteSetting.allow_uppercase_posts,
capitalize_first_letter: SiteSetting.title_prettify,
remove_all_periods_from_the_end: SiteSetting.title_prettify,
remove_extraneous_space: SiteSetting.title_prettify && SiteSetting.default_locale == "en",
remove_extraneous_space: SiteSetting.title_prettify && SiteSetting.title_remove_extraneous_space,
fixes_interior_spaces: true,
strip_whitespaces: true,
strip_zero_width_spaces: true
Expand Down
Loading

0 comments on commit b788948

Please sign in to comment.