From 1506eba28dbc883b51b4f99e251dcafafb37181c Mon Sep 17 00:00:00 2001 From: Robin Ward <robin.ward@gmail.com> Date: Fri, 20 Nov 2015 17:13:37 -0500 Subject: [PATCH] Support for overriding client side translation keys --- .../initializers/localization.js.es6 | 28 ++++++++++++ .../initializers/verbose-localization.js.es6 | 11 ----- app/controllers/application_controller.rb | 1 + lib/freedom_patches/translate_accelerator.rb | 43 ++++++++++++------- spec/components/discourse_i18n_spec.rb | 19 ++++++++ 5 files changed, 75 insertions(+), 27 deletions(-) create mode 100644 app/assets/javascripts/discourse/initializers/localization.js.es6 delete mode 100644 app/assets/javascripts/discourse/initializers/verbose-localization.js.es6 diff --git a/app/assets/javascripts/discourse/initializers/localization.js.es6 b/app/assets/javascripts/discourse/initializers/localization.js.es6 new file mode 100644 index 000000000..5c9f3292c --- /dev/null +++ b/app/assets/javascripts/discourse/initializers/localization.js.es6 @@ -0,0 +1,28 @@ +export default { + name: 'localization', + after: 'inject-objects', + + initialize: function(container) { + const siteSettings = container.lookup('site-settings:main'); + if (siteSettings.verbose_localization) { + I18n.enable_verbose_localization(); + } + + // Merge any overrides into our object + const overrides = PreloadStore.get('translationOverrides') || {}; + Object.keys(overrides).forEach(k => { + const v = overrides[k]; + + const segs = k.split('.'); + let node = I18n.translations[I18n.locale]; + let i = 0; + for (; node && i<segs.length-1; i++) { + node = node[segs[i]]; + } + + if (node && i == segs.length-1) { + node[segs[segs.length-1]] = v; + } + }); + } +}; diff --git a/app/assets/javascripts/discourse/initializers/verbose-localization.js.es6 b/app/assets/javascripts/discourse/initializers/verbose-localization.js.es6 deleted file mode 100644 index 71aca9f3f..000000000 --- a/app/assets/javascripts/discourse/initializers/verbose-localization.js.es6 +++ /dev/null @@ -1,11 +0,0 @@ -export default { - name: 'verbose-localization', - after: 'inject-objects', - - initialize: function(container) { - var siteSettings = container.lookup('site-settings:main'); - if (siteSettings.verbose_localization) { - I18n.enable_verbose_localization(); - } - } -}; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d162e27f0..b9e597151 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -288,6 +288,7 @@ class ApplicationController < ActionController::Base store_preloaded("customHTML", custom_html_json) store_preloaded("banner", banner_json) store_preloaded("customEmoji", custom_emoji) + store_preloaded("translationOverrides", I18n.client_overrides_json) end def preload_current_user_data diff --git a/lib/freedom_patches/translate_accelerator.rb b/lib/freedom_patches/translate_accelerator.rb index 68ac930c9..4bdeaf5cd 100644 --- a/lib/freedom_patches/translate_accelerator.rb +++ b/lib/freedom_patches/translate_accelerator.rb @@ -72,26 +72,37 @@ module I18n end end + def overrides_by_locale + return unless @overrides_enabled + + site = RailsMultisite::ConnectionManagement.current_db + + by_site = @overrides_by_site[site] + + by_locale = nil + unless by_site + by_site = @overrides_by_site[site] = {} + + # Load overrides + TranslationOverride.where(locale: locale).pluck(:translation_key, :value).each do |tuple| + by_locale = by_site[locale] ||= {} + by_locale[tuple[0]] = tuple[1] + end + end + + by_site[config.locale] + end + + def client_overrides_json + client_json = (overrides_by_locale || {}).select {|k, _| k.starts_with?('js.')} + MultiJson.dump(client_json) + end + def translate(key, *args) load_locale(config.locale) unless @loaded_locales.include?(config.locale) if @overrides_enabled - site = RailsMultisite::ConnectionManagement.current_db - - by_site = @overrides_by_site[site] - - by_locale = nil - unless by_site - by_site = @overrides_by_site[site] = {} - - # Load overrides - TranslationOverride.where(locale: locale).pluck(:translation_key, :value).each do |tuple| - by_locale = by_site[locale] ||= {} - by_locale[tuple[0]] = tuple[1] - end - end - - by_locale = by_site[config.locale] + by_locale = overrides_by_locale if by_locale if args.size > 0 && args[0].is_a?(Hash) args[0][:overrides] = by_locale diff --git a/spec/components/discourse_i18n_spec.rb b/spec/components/discourse_i18n_spec.rb index 551c05aa3..dc6cd2293 100644 --- a/spec/components/discourse_i18n_spec.rb +++ b/spec/components/discourse_i18n_spec.rb @@ -91,6 +91,25 @@ describe I18n::Backend::DiscourseI18n do expect(I18n.translate('items', count: 13)).to eq('13 fishies') expect(I18n.translate('items', count: 1)).to eq('one fish') end + + describe "client json" do + it "is empty by default" do + expect(I18n.client_overrides_json).to eq("{}") + end + + it "doesn't return server overrides" do + TranslationOverride.upsert!('en', 'foo', 'bar') + expect(I18n.client_overrides_json).to eq("{}") + end + + it "returns client overrides" do + TranslationOverride.upsert!('en', 'js.foo', 'bar') + json = ::JSON.parse(I18n.client_overrides_json) + + expect(json).to be_present + expect(json['js.foo']).to eq('bar') + end + end end end