Support for other i18n bundles

This commit is contained in:
Robin Ward 2016-08-25 16:33:29 -04:00
parent 7acbd63d92
commit 6070939daa
6 changed files with 103 additions and 15 deletions

View File

@ -92,6 +92,24 @@ I18n.isValidNode = function(obj, node, undefined) {
return obj[node] !== null && obj[node] !== undefined;
};
function checkExtras(origScope, sep, extras) {
if (!extras || extras.length === 0) { return; }
for (var i=0; i<extras.length; i++) {
var messages = extras[i];
scope = origScope.split(sep);
scope.shift();
while (messages && scope.length > 0) {
currentScope = scope.shift();
messages = messages[currentScope];
}
if (messages) {
return messages;
}
}
}
I18n.lookup = function(scope, options) {
options = options || {};
var lookupInitialScope = scope,
@ -110,13 +128,20 @@ I18n.lookup = function(scope, options) {
scope = options.scope.toString() + this.defaultSeparator + scope;
}
scope = scope.split(this.defaultSeparator);
var origScope = "" + scope;
scope = origScope.split(this.defaultSeparator);
while (messages && scope.length > 0) {
currentScope = scope.shift();
messages = messages[currentScope];
}
if (!messages) {
messages = checkExtras(origScope, this.defaultSeparator, this.extras);
}
if (!messages) {
if (I18n.fallbacks) {
var fallbacks = this.getFallbacks(locale);
@ -192,7 +217,9 @@ I18n.interpolate = function(message, options) {
};
I18n.translate = function(scope, options) {
options = this.prepareOptions(options);
var translation = this.lookup(scope, options);
// Fallback to the default locale
if (!translation && this.currentLocale() !== this.defaultLocale && !this.noFallbacks) {

View File

@ -0,0 +1,31 @@
class ExtraLocalesController < ApplicationController
layout :false
skip_before_filter :check_xhr, :preload_json
def show
locale_str = I18n.locale.to_s
translations = JsLocaleHelper.translations_for(locale_str)
bundle = params[:bundle]
raise Discourse::InvalidAccess.new unless bundle =~ /^[a-z]+$/
for_key = translations[locale_str]["#{bundle}_js"]
if for_key.present?
js = <<-JS
(function() {
if (window.I18n) {
window.I18n.extras = window.I18n.extras || [];
window.I18n.extras.push(#{for_key.to_json});
}
})();
JS
else
js = ""
end
render text: js, content_type: "application/javascript"
end
end

View File

@ -30,6 +30,7 @@
<%= script "application" %>
<%- if staff? %>
<script src="/extra-locales/admin"></script>
<%= script "admin" %>
<%- end %>

View File

@ -163,6 +163,7 @@ Discourse::Application.routes.draw do
get "customize/permalinks" => "permalinks#index", constraints: AdminConstraint.new
get "customize/embedding" => "embedding#show", constraints: AdminConstraint.new
put "customize/embedding" => "embedding#update", constraints: AdminConstraint.new
get "flags" => "flags#index"
get "flags/:filter" => "flags#index"
post "flags/agree/:id" => "flags#agree"
@ -251,6 +252,8 @@ Discourse::Application.routes.draw do
get "email/unsubscribed" => "email#unsubscribed", as: "email_unsubscribed"
post "email/unsubscribe/:key" => "email#perform_unsubscribe", as: "email_perform_unsubscribe"
get "extra-locales/:bundle" => "extra_locales#show"
resources :session, id: USERNAME_ROUTE_FORMAT, only: [:create, :destroy, :become] do
get 'become'
collection do

View File

@ -20,15 +20,6 @@ module JsLocaleHelper
# merge translations (plugin translations overwrite default translations)
translations[locale_str]['js'].deep_merge!(plugin_translations[locale_str]['js']) if translations[locale_str] && plugin_translations[locale_str] && plugin_translations[locale_str]['js']
# We used to split the admin versus the client side, but it's much simpler to just
# include both for now due to the small size of the admin section.
#
# For now, let's leave it split out in the translation file in case we want to split
# it again later, so we'll merge the JSON ourselves.
admin_contents = translations[locale_str].delete('admin_js')
translations[locale_str]['js'].deep_merge!(admin_contents) if admin_contents.present?
translations[locale_str]['js'].deep_merge!(plugin_translations[locale_str]['admin_js']) if translations[locale_str] && plugin_translations[locale_str] && plugin_translations[locale_str]['admin_js']
translations
end
end
@ -72,9 +63,8 @@ module JsLocaleHelper
end
end
def self.output_locale(locale)
locale_sym = locale.to_sym
locale_str = locale.to_s
def self.translations_for(locale_str)
locale_sym = locale_str.to_sym
current_locale = I18n.locale
I18n.locale = locale_sym
@ -93,6 +83,19 @@ module JsLocaleHelper
end
end
I18n.locale = current_locale
translations
end
def self.output_locale(locale)
locale_str = locale.to_s
translations = translations_for(locale_str).dup
translations[locale_str].keys.each do |k|
translations[locale_str].delete(k) unless k == "js"
end
message_formats = strip_out_message_formats!(translations[locale_str]['js'])
result = generate_message_format(message_formats, locale_str)
@ -104,8 +107,6 @@ module JsLocaleHelper
result << moment_locale(locale_str)
result << moment_formats
I18n.locale = current_locale
result
end

View File

@ -0,0 +1,25 @@
require 'rails_helper'
describe ExtraLocalesController do
context 'show' do
it "needs a valid bundle" do
get :show, bundle: 'made-up-bundle'
expect(response).to_not be_success
expect(response.body).to be_blank
end
it "won't work with a weird parameter" do
get :show, bundle: '-invalid..character!!'
expect(response).to_not be_success
end
it "works with a valid bundle" do
get :show, bundle: 'admin'
expect(response).to be_success
expect(response.body).to be_present
end
end
end