Refactor to our own Discourse I18n backend
This removes some monkey patches and makes testing easier. It will also support database backed I18n changes.
This commit is contained in:
parent
43614439e6
commit
3720783c1b
|
@ -138,13 +138,8 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def set_locale
|
||||
I18n.locale = if current_user
|
||||
current_user.effective_locale
|
||||
else
|
||||
SiteSetting.default_locale
|
||||
end
|
||||
|
||||
I18n.fallbacks.ensure_loaded!
|
||||
I18n.locale = current_user.try(:effective_locale) || SiteSetting.default_locale
|
||||
I18n.ensure_all_loaded!
|
||||
end
|
||||
|
||||
def store_preloaded(key, json)
|
||||
|
|
|
@ -149,7 +149,7 @@ module Jobs
|
|||
begin
|
||||
RailsMultisite::ConnectionManagement.establish_connection(db: db)
|
||||
I18n.locale = SiteSetting.default_locale
|
||||
I18n.fallbacks.ensure_loaded!
|
||||
I18n.ensure_all_loaded!
|
||||
begin
|
||||
execute(opts)
|
||||
rescue => e
|
||||
|
|
|
@ -1,26 +1,5 @@
|
|||
# order: after 02-freedom_patches.rb
|
||||
|
||||
# Include pluralization module
|
||||
require 'i18n/backend/pluralization'
|
||||
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
|
||||
|
||||
# Include fallbacks module
|
||||
require 'i18n/backend/fallbacks'
|
||||
I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
|
||||
|
||||
# Configure custom fallback order
|
||||
class FallbackLocaleList < Hash
|
||||
def [](locale)
|
||||
# user locale, site locale, english
|
||||
# TODO - this can be extended to be per-language for a better user experience
|
||||
# (e.g. fallback zh_TW to zh_CN / vice versa)
|
||||
[locale, SiteSetting.default_locale.to_sym, :en].uniq.compact
|
||||
end
|
||||
|
||||
def ensure_loaded!
|
||||
self[I18n.locale].each { |l| I18n.ensure_loaded! l }
|
||||
end
|
||||
end
|
||||
|
||||
I18n.fallbacks = FallbackLocaleList.new
|
||||
require 'i18n/backend/discourse_i18n'
|
||||
I18n.backend = I18n::Backend::DiscourseI18n.new
|
||||
I18n.config.missing_interpolation_argument_handler = proc { throw(:exception) }
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# This should be used until https://github.com/svenfuchs/i18n/pull/326 is merged into the I18n gem.
|
||||
|
||||
module I18n
|
||||
module Backend
|
||||
module Fallbacks
|
||||
def exists?(locale, key)
|
||||
I18n.fallbacks[locale].each do |fallback|
|
||||
begin
|
||||
return true if super(fallback, key)
|
||||
rescue I18n::InvalidLocale
|
||||
# we do nothing when the locale is invalid, as this is a fallback anyways.
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,27 +9,7 @@
|
|||
# This patch depends on the convention that locale yml files must be named [locale_name].yml
|
||||
|
||||
module I18n
|
||||
module Backend
|
||||
|
||||
class Simple
|
||||
def available_locales
|
||||
# in case you are wondering this is:
|
||||
# Dir.glob( File.join(Rails.root, 'config', 'locales', 'client.*.yml') )
|
||||
# .map {|x| x.split('.')[-2]}.sort
|
||||
LocaleSiteSetting.supported_locales.map(&:to_sym)
|
||||
end
|
||||
end
|
||||
|
||||
module Base
|
||||
# force explicit loading
|
||||
def load_translations(*filenames)
|
||||
unless filenames.empty?
|
||||
filenames.flatten.each { |filename| load_file(filename) }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
# this accelerates translation a tiny bit (halves the time it takes)
|
||||
class << self
|
||||
alias_method :translate_no_cache, :translate
|
||||
|
@ -59,9 +39,13 @@ module I18n
|
|||
end
|
||||
end
|
||||
|
||||
def ensure_all_loaded!
|
||||
backend.fallbacks(locale).each {|l| ensure_loaded!(l) }
|
||||
end
|
||||
|
||||
def ensure_loaded!(locale)
|
||||
@loaded_locales ||= []
|
||||
load_locale locale unless @loaded_locales.include?(locale)
|
||||
load_locale(locale) unless @loaded_locales.include?(locale)
|
||||
end
|
||||
|
||||
def translate(key, *args)
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
require 'i18n/backend/pluralization'
|
||||
|
||||
module I18n
|
||||
module Backend
|
||||
class DiscourseI18n < I18n::Backend::Simple
|
||||
include I18n::Backend::Pluralization
|
||||
|
||||
def available_locales
|
||||
# in case you are wondering this is:
|
||||
# Dir.glob( File.join(Rails.root, 'config', 'locales', 'client.*.yml') )
|
||||
# .map {|x| x.split('.')[-2]}.sort
|
||||
LocaleSiteSetting.supported_locales.map(&:to_sym)
|
||||
end
|
||||
|
||||
# force explicit loading
|
||||
def load_translations(*filenames)
|
||||
unless filenames.empty?
|
||||
filenames.flatten.each { |filename| load_file(filename) }
|
||||
end
|
||||
end
|
||||
|
||||
def fallbacks(locale)
|
||||
[locale, SiteSetting.default_locale.to_sym, :en].uniq.compact
|
||||
end
|
||||
|
||||
def exists?(locale, key)
|
||||
fallbacks(locale).each do |fallback|
|
||||
begin
|
||||
return true if super(fallback, key)
|
||||
rescue I18n::InvalidLocale
|
||||
# we do nothing when the locale is invalid, as this is a fallback anyways.
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
require 'spec_helper'
|
||||
require 'i18n/backend/discourse_i18n'
|
||||
|
||||
describe I18n::Backend::DiscourseI18n do
|
||||
|
||||
let(:backend) { I18n::Backend::DiscourseI18n.new }
|
||||
|
||||
before do
|
||||
backend.store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en')
|
||||
backend.store_translations(:en, :items => {:one => 'one item', :other => "%{count} items" })
|
||||
backend.store_translations(:de, :bar => 'Bar in :de')
|
||||
backend.store_translations(:'de-AT', :baz => 'Baz in :de-AT')
|
||||
end
|
||||
|
||||
it 'translates the basics as expected' do
|
||||
expect(backend.translate(:en, 'foo')).to eq("Foo in :en")
|
||||
expect(backend.translate(:en, 'items', count: 1)).to eq("one item")
|
||||
expect(backend.translate(:en, 'items', count: 3)).to eq("3 items")
|
||||
end
|
||||
|
||||
describe '#exists?' do
|
||||
it 'returns true when a key is given that exists' do
|
||||
expect(backend.exists?(:de, :bar)).to eq(true)
|
||||
end
|
||||
|
||||
it 'returns true when a key is given that exists in a fallback locale of the locale' do
|
||||
expect(backend.exists?(:de, :foo)).to eq(true)
|
||||
end
|
||||
|
||||
it 'returns true when an existing key and an existing locale is given' do
|
||||
expect(backend.exists?(:en, :foo)).to eq(true)
|
||||
expect(backend.exists?(:de, :bar)).to eq(true)
|
||||
expect(backend.exists?(:'de-AT', :baz)).to eq(true)
|
||||
end
|
||||
|
||||
it 'returns false when a non-existing key and an existing locale is given' do
|
||||
expect(backend.exists?(:en, :bogus)).to eq(false)
|
||||
expect(backend.exists?(:de, :bogus)).to eq(false)
|
||||
expect(backend.exists?(:'de-AT', :bogus)).to eq(false)
|
||||
end
|
||||
|
||||
it 'returns true when a key is given which is missing from the given locale and exists in a fallback locale' do
|
||||
expect(backend.exists?(:de, :foo)).to eq(true)
|
||||
expect(backend.exists?(:'de-AT', :foo)).to eq(true)
|
||||
end
|
||||
|
||||
it 'returns true when a key is given which is missing from the given locale and all its fallback locales' do
|
||||
expect(backend.exists?(:de, :baz)).to eq(false)
|
||||
expect(backend.exists?(:'de-AT', :bogus)).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'freedom patch for I18n::Backend::Fallbacks' do
|
||||
before do
|
||||
SiteSetting.default_locale = 'de'
|
||||
I18n.locale = :de
|
||||
|
||||
store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en')
|
||||
store_translations(:de, :bar => 'Bar in :de')
|
||||
store_translations(:'de-AT', :baz => 'Baz in :de-AT')
|
||||
end
|
||||
|
||||
def store_translations(locale, data)
|
||||
I18n.backend.store_translations(locale, data)
|
||||
end
|
||||
|
||||
describe '#exists?' do
|
||||
it 'returns true when a key is given that exists in the default locale' do
|
||||
expect(I18n.exists?(:bar)).to be true
|
||||
end
|
||||
|
||||
it 'returns true when a key is given that exists in a fallback locale of the default locale' do
|
||||
expect(I18n.exists?(:foo)).to be true
|
||||
end
|
||||
|
||||
it 'returns false when a non-existing key is given' do
|
||||
expect(I18n.exists?(:bogus)).to be false
|
||||
end
|
||||
|
||||
it 'returns true when an existing key and an existing locale is given' do
|
||||
expect(I18n.exists?(:foo, :en)).to be true
|
||||
expect(I18n.exists?(:bar, :de)).to be true
|
||||
expect(I18n.exists?(:baz, :'de-AT')).to be true
|
||||
end
|
||||
|
||||
it 'returns false when a non-existing key and an existing locale is given' do
|
||||
expect(I18n.exists?(:bogus, :en)).to be false
|
||||
expect(I18n.exists?(:bogus, :de)).to be false
|
||||
expect(I18n.exists?(:bogus, :'de-AT')).to be false
|
||||
end
|
||||
|
||||
it 'returns true when a key is given which is missing from the given locale and exists in a fallback locale' do
|
||||
expect(I18n.exists?(:foo, :de)).to be true
|
||||
expect(I18n.exists?(:foo, :'de-AT')).to be true
|
||||
end
|
||||
|
||||
it 'returns true when a key is given which is missing from the given locale and all its fallback locales' do
|
||||
expect(I18n.exists?(:baz, :de)).to be false
|
||||
expect(I18n.exists?(:bogus, :'de-AT')).to be false
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue