mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
FIX: Allow message format translations to be overridden
This commit is contained in:
parent
adb3810f67
commit
cc25716e47
9 changed files with 84 additions and 27 deletions
|
@ -12,8 +12,16 @@ export default {
|
|||
const overrides = PreloadStore.get('translationOverrides') || {};
|
||||
Object.keys(overrides).forEach(k => {
|
||||
const v = overrides[k];
|
||||
k = k.replace('admin_js', 'js');
|
||||
|
||||
// Special case: Message format keys are functions
|
||||
if (/\_MF$/.test(k)) {
|
||||
k = k.replace(/^[a-z_]*js\./, '');
|
||||
I18n._compiledMFs[k] = new Function('transKey', `return (${v})(transKey);`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
k = k.replace('admin_js', 'js');
|
||||
const segs = k.split('.');
|
||||
let node = I18n.translations[I18n.locale];
|
||||
let i = 0;
|
||||
|
|
|
@ -14,12 +14,12 @@ class Admin::SiteTextsController < Admin::AdminController
|
|||
query = params[:q] || ""
|
||||
if query.blank? && !overridden
|
||||
extras[:recommended] = true
|
||||
results = self.class.preferred_keys.map {|k| {id: k, value: I18n.t(k) }}
|
||||
results = self.class.preferred_keys.map {|k| record_for(k) }
|
||||
else
|
||||
results = []
|
||||
translations = I18n.search(query, overridden: overridden)
|
||||
translations.each do |k, v|
|
||||
results << {id: k, value: v}
|
||||
results << record_for(k, v)
|
||||
end
|
||||
|
||||
results.sort! do |x, y|
|
||||
|
@ -62,9 +62,19 @@ class Admin::SiteTextsController < Admin::AdminController
|
|||
|
||||
protected
|
||||
|
||||
def record_for(k, value=nil)
|
||||
if k.ends_with?("_MF")
|
||||
ovr = TranslationOverride.where(translation_key: k).pluck(:value)
|
||||
value = ovr[0] if ovr.present?
|
||||
end
|
||||
|
||||
value ||= I18n.t(k)
|
||||
{id: k, value: value}
|
||||
end
|
||||
|
||||
def find_site_text
|
||||
raise Discourse::NotFound unless I18n.exists?(params[:id])
|
||||
{id: params[:id], value: I18n.t(params[:id]) }
|
||||
record_for(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
require 'js_locale_helper'
|
||||
|
||||
class TranslationOverride < ActiveRecord::Base
|
||||
validates_uniqueness_of :translation_key, scope: :locale
|
||||
validates_presence_of :locale, :translation_key, :value
|
||||
|
||||
def self.upsert!(locale, key, value)
|
||||
params = { locale: locale, translation_key: key }
|
||||
row_count = where(params).update_all(value: value)
|
||||
create!(params.merge(value: value)) if row_count == 0
|
||||
|
||||
data = { value: value }
|
||||
if key.end_with?('_MF')
|
||||
data[:compiled_js] = JsLocaleHelper.compile_message_format(locale, value)
|
||||
end
|
||||
|
||||
row_count = where(params).update_all(data)
|
||||
create!(params.merge(data)) if row_count == 0
|
||||
i18n_changed
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddCompiledJsToTranslationOverrides < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :translation_overrides, :compiled_js, :text, null: true
|
||||
end
|
||||
end
|
|
@ -110,14 +110,14 @@ module I18n
|
|||
by_site = @overrides_by_site[site] = {}
|
||||
|
||||
# Load overrides
|
||||
translations_overrides = TranslationOverride.where(locale: locale).pluck(:translation_key, :value)
|
||||
translations_overrides = TranslationOverride.where(locale: locale).pluck(:translation_key, :value, :compiled_js)
|
||||
|
||||
if translations_overrides.empty?
|
||||
by_site[locale] = {}
|
||||
else
|
||||
translations_overrides.each do |tuple|
|
||||
by_locale = by_site[locale] ||= {}
|
||||
by_locale[tuple[0]] = tuple[1]
|
||||
by_locale[tuple[0]] = tuple[2] || tuple[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
17
lib/javascripts/messageformat-lookup.js
Normal file
17
lib/javascripts/messageformat-lookup.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
(function() {
|
||||
|
||||
I18n.messageFormat = function(key, options) {
|
||||
var fn = I18n._compiledMFs[key];
|
||||
if (fn) {
|
||||
try {
|
||||
return fn(options);
|
||||
} catch(err) {
|
||||
return err.message;
|
||||
}
|
||||
} else {
|
||||
return 'Missing Key: ' + key;
|
||||
}
|
||||
return I18n._compiledMFs[key](options);
|
||||
};
|
||||
|
||||
})();
|
|
@ -139,31 +139,19 @@ module JsLocaleHelper
|
|||
end
|
||||
|
||||
def self.generate_message_format(message_formats, locale_str)
|
||||
formats = message_formats.map{|k,v| k.inspect << " : " << compile_message_format(locale_str ,v)}.join(" , ")
|
||||
|
||||
result = "MessageFormat = {locale: {}};\n"
|
||||
|
||||
formats = message_formats.map{|k,v| k.inspect << " : " << compile_message_format(locale_str,v)}.join(", ")
|
||||
result << "I18n._compiledMFs = {#{formats}};\n\n"
|
||||
|
||||
filename = Rails.root + "lib/javascripts/locale/#{locale_str}.js"
|
||||
filename = Rails.root + "lib/javascripts/locale/en.js" unless File.exists?(filename)
|
||||
result << File.read(filename) << "\n\n"
|
||||
|
||||
result << File.read(filename) << "\n"
|
||||
result << File.read("#{Rails.root}/lib/javascripts/messageformat-lookup.js")
|
||||
|
||||
result << "I18n.messageFormat = (function(formats){
|
||||
var f = formats;
|
||||
return function(key, options) {
|
||||
var fn = f[key];
|
||||
if(fn){
|
||||
try {
|
||||
return fn(options);
|
||||
} catch(err) {
|
||||
return err.message;
|
||||
}
|
||||
} else {
|
||||
return 'Missing Key: ' + key
|
||||
}
|
||||
return f[key](options);
|
||||
};
|
||||
})({#{formats}});"
|
||||
result
|
||||
end
|
||||
|
||||
def self.compile_message_format(locale, format)
|
||||
|
|
|
@ -54,7 +54,6 @@ describe JsLocaleHelper do
|
|||
other {# apples}
|
||||
}')
|
||||
|
||||
|
||||
expect(localize(NUM_RESULTS: 1, NUM_APPLES: 2)).to eq('1 result and 2 apples')
|
||||
expect(localize(NUM_RESULTS: 2, NUM_APPLES: 1)).to eq('2 results and 1 apple')
|
||||
end
|
||||
|
|
22
spec/models/translation_override_spec.rb
Normal file
22
spec/models/translation_override_spec.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe TranslationOverride do
|
||||
|
||||
it "upserts values" do
|
||||
TranslationOverride.upsert!('en', 'some.key', 'some value')
|
||||
|
||||
ovr = TranslationOverride.where(locale: 'en', translation_key: 'some.key').first
|
||||
expect(ovr).to be_present
|
||||
expect(ovr.value).to eq('some value')
|
||||
end
|
||||
|
||||
it "stores js for a message format key" do
|
||||
TranslationOverride.upsert!('en', 'some.key_MF', '{NUM_RESULTS, plural, one {1 result} other {many} }')
|
||||
|
||||
ovr = TranslationOverride.where(locale: 'en', translation_key: 'some.key_MF').first
|
||||
expect(ovr).to be_present
|
||||
expect(ovr.compiled_js).to match(/function/)
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in a new issue