Module: I18n
- Defined in:
- lib/freedom_patches/translate_accelerator.rb,
lib/i18n/backend/discourse_i18n.rb,
lib/i18n/backend/fallback_locale_list.rb
Overview
This patch performs 2 functions
-
It caches all translations which drastically improves translation performance in an LRU cache
-
It patches I18n so it only loads the translations it needs on demand
This patch depends on the convention that locale yml files must be named [locale_name].yml
Defined Under Namespace
Modules: Backend
Classes: MissingTranslation
Constant Summary
collapse
- LRU_CACHE_SIZE =
400
- LOAD_MUTEX =
Mutex.new
Class Method Summary
collapse
Class Method Details
.add_if_matches(translations, results, regexp) ⇒ Object
95
96
97
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 95
def add_if_matches(translations, results, regexp)
translations.each { |key, value| results[key] = value if key =~ regexp || value =~ regexp }
end
|
.ensure_all_loaded! ⇒ Object
68
69
70
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 68
def ensure_all_loaded!
I18n.fallbacks[locale].each { |l| ensure_loaded!(l) }
end
|
.ensure_loaded!(locale) ⇒ Object
99
100
101
102
103
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 99
def ensure_loaded!(locale)
locale = locale.to_sym
@loaded_locales ||= []
load_locale(locale) unless @loaded_locales.include?(locale)
end
|
.exists?(key, locale = nil) ⇒ Boolean
231
232
233
234
235
236
237
238
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 231
def exists?(key, locale = nil)
execute_reload if @requires_reload
locale ||= config.locale
locale = locale.to_sym
load_locale(locale) unless @loaded_locales.include?(locale)
exists_no_cache?(key, locale)
end
|
.exists_no_cache? ⇒ Object
17
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 17
alias_method :exists_no_cache?, :exists?
|
.init_accelerator!(overrides_enabled: true) ⇒ Object
23
24
25
26
27
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 23
def init_accelerator!(overrides_enabled: true)
@overrides_enabled = overrides_enabled
reserve_key(:overrides)
execute_reload
end
|
.load_locale(locale) ⇒ Object
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 35
def load_locale(locale)
locale = locale.to_sym
LOAD_MUTEX.synchronize do
return if @loaded_locales.include?(locale)
if @loaded_locales.empty?
I18n.backend.load_translations(I18n.load_path.grep(/\.rb\z/))
DiscoursePluginRegistry.locales.each do |plugin_locale, options|
if options[:plural]
I18n.backend.store_translations(plugin_locale, i18n: { plural: options[:plural] })
end
end
end
I18n.backend.load_translations(I18n.load_path.grep(/\.#{Regexp.escape locale}\.yml\z/))
if Discourse.allow_dev_populate? || Rails.env.test? || Rails.env.development?
I18n.backend.load_translations(
I18n.load_path.grep(%r{.*faker.*/#{Regexp.escape locale}\.yml\z}),
)
I18n.backend.load_translations(
I18n.load_path.grep(%r{.*faker.*/#{Regexp.escape locale}/.*\.yml\z}),
)
end
@loaded_locales << locale
end
end
|
.locale=(value) ⇒ Object
240
241
242
243
244
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 240
def locale=(value)
value = value.to_sym
execute_reload if @requires_reload
self.locale_no_cache = value
end
|
.locale_no_cache= ⇒ Object
19
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 19
alias_method :locale_no_cache=, :locale=
|
.overrides_by_locale(locale) ⇒ Object
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 155
def overrides_by_locale(locale)
return {} unless @overrides_enabled
return {} if GlobalSetting.skip_db?
locale = locale.to_sym
execute_reload if @requires_reload
site = RailsMultisite::ConnectionManagement.current_db
by_site = @overrides_by_site[site]
by_site ||= {}
if !by_site.has_key?(locale)
translations_overrides =
TranslationOverride.where(locale: locale).pluck(:translation_key, :value)
if translations_overrides.empty?
by_site[locale] = {}
else
translations_overrides.each do |tuple|
by_locale = by_site[locale] ||= {}
by_locale[tuple[0]] = tuple[1]
end
end
@overrides_by_site[site] = by_site
end
by_site[locale].with_indifferent_access
rescue ActiveRecord::StatementInvalid => e
if PG::UndefinedTable === e.cause || PG::UndefinedColumn === e.cause
{}
else
raise
end
end
|
.overrides_disabled ⇒ Object
In some environments such as migrations we don’t want to use overrides. Use this to disable them over a block of ruby code
107
108
109
110
111
112
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 107
def overrides_disabled
@overrides_enabled = false
yield
ensure
@overrides_enabled = true
end
|
.reload! ⇒ Object
29
30
31
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 29
def reload!
@requires_reload = true
end
|
.reload_no_cache! ⇒ Object
18
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 18
alias_method :reload_no_cache!, :reload!
|
.search(query, opts = {}) ⇒ Object
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 72
def search(query, opts = {})
execute_reload if @requires_reload
locale = (opts[:locale] || config.locale).to_sym
load_locale(locale) unless @loaded_locales.include?(locale)
results = {}
regexp = I18n::Backend::DiscourseI18n.create_search_regexp(query)
if opts[:only_overridden]
add_if_matches(overrides_by_locale(locale), results, regexp)
else
target = opts[:backend] || backend
I18n.fallbacks[locale].reverse_each do |fallback|
add_if_matches(target.search(fallback, query), results, regexp)
add_if_matches(overrides_by_locale(fallback), results, regexp)
end
end
results
end
|
.translate(*args) ⇒ Object
Also known as:
t
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 193
def translate(*args)
execute_reload if @requires_reload
options = args.last.is_a?(Hash) ? args.pop.dup : {}
key = args.shift
locale = (options[:locale] || config.locale).to_sym
load_locale(locale) unless @loaded_locales.include?(locale)
if @overrides_enabled
overrides = {}
has_count = options.has_key?(:count)
I18n.fallbacks[locale].each do |l|
overrides_for_locale = overrides_by_locale(l)
overrides[l] = overrides_for_locale if has_count || overrides_for_locale.key?(key)
end
if overrides.present?
no_options = options.empty? || (options.size == 1 && options.has_key?(:locale))
if no_options && (override = overrides.dig(locale, key))
return override
end
options[:overrides] = overrides
catch(:exception) { return backend.translate(locale, key, options) }
end
end
translate_no_override(key, options)
end
|
.translate_no_cache ⇒ Object
16
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 16
alias_method :translate_no_cache, :translate
|
.translate_no_override(key, options) ⇒ Object
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/freedom_patches/translate_accelerator.rb', line 117
def translate_no_override(key, options)
should_raise = false
locale = nil
dup_options = nil
if options
dup_options = options.dup
should_raise = dup_options.delete(:raise)
locale = dup_options.delete(:locale)
end
return translate_no_cache(key, **options) if dup_options.present?
locale ||= config.locale
locale = locale.to_sym
@cache ||= LruRedux::ThreadSafeCache.new(LRU_CACHE_SIZE)
k = "#{key}#{locale}#{config.backend.object_id}"
val =
@cache.getset(k) do
begin
translate_no_cache(key, locale: locale, raise: true).freeze
rescue I18n::MissingTranslationData
MissingTranslation
end
end
if val != MissingTranslation
val
elsif should_raise
raise I18n::MissingTranslationData.new(locale, key)
else
-"Translation missing: #{locale}.#{key}"
end
end
|