i18n 1.0.0 → 1.14.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +75 -32
- data/lib/i18n/backend/base.rb +93 -34
- data/lib/i18n/backend/cache.rb +10 -11
- data/lib/i18n/backend/cache_file.rb +36 -0
- data/lib/i18n/backend/cascade.rb +3 -1
- data/lib/i18n/backend/chain.rb +39 -6
- data/lib/i18n/backend/fallbacks.rb +48 -15
- data/lib/i18n/backend/flatten.rb +10 -5
- data/lib/i18n/backend/gettext.rb +4 -2
- data/lib/i18n/backend/interpolation_compiler.rb +8 -8
- data/lib/i18n/backend/key_value.rb +31 -4
- data/lib/i18n/backend/lazy_loadable.rb +184 -0
- data/lib/i18n/backend/memoize.rb +10 -2
- data/lib/i18n/backend/metadata.rb +5 -3
- data/lib/i18n/backend/pluralization.rb +61 -18
- data/lib/i18n/backend/simple.rb +44 -24
- data/lib/i18n/backend/transliterator.rb +26 -24
- data/lib/i18n/backend.rb +5 -1
- data/lib/i18n/config.rb +22 -4
- data/lib/i18n/exceptions.rb +71 -18
- data/lib/i18n/gettext/helpers.rb +4 -2
- data/lib/i18n/gettext/po_parser.rb +7 -7
- data/lib/i18n/gettext.rb +2 -0
- data/lib/i18n/interpolate/ruby.rb +22 -6
- data/lib/i18n/locale/fallbacks.rb +33 -22
- data/lib/i18n/locale/tag/parents.rb +8 -6
- data/lib/i18n/locale/tag/simple.rb +2 -2
- data/lib/i18n/locale.rb +2 -0
- data/lib/i18n/middleware.rb +2 -0
- data/lib/i18n/tests/basics.rb +5 -7
- data/lib/i18n/tests/defaults.rb +8 -1
- data/lib/i18n/tests/interpolation.rb +34 -7
- data/lib/i18n/tests/link.rb +11 -1
- data/lib/i18n/tests/localization/date.rb +37 -10
- data/lib/i18n/tests/localization/date_time.rb +28 -7
- data/lib/i18n/tests/localization/procs.rb +9 -7
- data/lib/i18n/tests/localization/time.rb +27 -5
- data/lib/i18n/tests/lookup.rb +11 -5
- data/lib/i18n/tests/pluralization.rb +1 -1
- data/lib/i18n/tests/procs.rb +23 -7
- data/lib/i18n/tests.rb +2 -0
- data/lib/i18n/utils.rb +55 -0
- data/lib/i18n/version.rb +3 -1
- data/lib/i18n.rb +179 -58
- metadata +16 -61
- data/gemfiles/Gemfile.rails-3.2.x +0 -10
- data/gemfiles/Gemfile.rails-4.0.x +0 -10
- data/gemfiles/Gemfile.rails-4.1.x +0 -10
- data/gemfiles/Gemfile.rails-4.2.x +0 -10
- data/gemfiles/Gemfile.rails-5.0.x +0 -10
- data/gemfiles/Gemfile.rails-5.1.x +0 -10
- data/gemfiles/Gemfile.rails-master +0 -10
- data/lib/i18n/core_ext/hash.rb +0 -29
- data/lib/i18n/core_ext/kernel/suppress_warnings.rb +0 -8
- data/lib/i18n/core_ext/string/interpolate.rb +0 -9
- data/test/api/all_features_test.rb +0 -58
- data/test/api/cascade_test.rb +0 -28
- data/test/api/chain_test.rb +0 -24
- data/test/api/fallbacks_test.rb +0 -30
- data/test/api/key_value_test.rb +0 -24
- data/test/api/memoize_test.rb +0 -56
- data/test/api/override_test.rb +0 -42
- data/test/api/pluralization_test.rb +0 -30
- data/test/api/simple_test.rb +0 -28
- data/test/backend/cache_test.rb +0 -109
- data/test/backend/cascade_test.rb +0 -86
- data/test/backend/chain_test.rb +0 -122
- data/test/backend/exceptions_test.rb +0 -36
- data/test/backend/fallbacks_test.rb +0 -219
- data/test/backend/interpolation_compiler_test.rb +0 -118
- data/test/backend/key_value_test.rb +0 -61
- data/test/backend/memoize_test.rb +0 -79
- data/test/backend/metadata_test.rb +0 -48
- data/test/backend/pluralization_test.rb +0 -45
- data/test/backend/simple_test.rb +0 -103
- data/test/backend/transliterator_test.rb +0 -84
- data/test/core_ext/hash_test.rb +0 -36
- data/test/gettext/api_test.rb +0 -214
- data/test/gettext/backend_test.rb +0 -92
- data/test/i18n/exceptions_test.rb +0 -117
- data/test/i18n/gettext_plural_keys_test.rb +0 -20
- data/test/i18n/interpolate_test.rb +0 -91
- data/test/i18n/load_path_test.rb +0 -34
- data/test/i18n/middleware_test.rb +0 -24
- data/test/i18n_test.rb +0 -462
- data/test/locale/fallbacks_test.rb +0 -133
- data/test/locale/tag/rfc4646_test.rb +0 -143
- data/test/locale/tag/simple_test.rb +0 -32
- data/test/run_all.rb +0 -20
- data/test/test_data/locales/de.po +0 -82
- data/test/test_data/locales/en.rb +0 -3
- data/test/test_data/locales/en.yml +0 -3
- data/test/test_data/locales/invalid/empty.yml +0 -0
- data/test/test_data/locales/invalid/syntax.yml +0 -4
- data/test/test_data/locales/plurals.rb +0 -113
- data/test/test_helper.rb +0 -61
data/lib/i18n/utils.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Utils
|
5
|
+
class << self
|
6
|
+
if Hash.method_defined?(:except)
|
7
|
+
def except(hash, *keys)
|
8
|
+
hash.except(*keys)
|
9
|
+
end
|
10
|
+
else
|
11
|
+
def except(hash, *keys)
|
12
|
+
hash = hash.dup
|
13
|
+
keys.each { |k| hash.delete(k) }
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def deep_merge(hash, other_hash, &block)
|
19
|
+
deep_merge!(hash.dup, other_hash, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def deep_merge!(hash, other_hash, &block)
|
23
|
+
hash.merge!(other_hash) do |key, this_val, other_val|
|
24
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
25
|
+
deep_merge(this_val, other_val, &block)
|
26
|
+
elsif block_given?
|
27
|
+
yield key, this_val, other_val
|
28
|
+
else
|
29
|
+
other_val
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def deep_symbolize_keys(hash)
|
35
|
+
hash.each_with_object({}) do |(key, value), result|
|
36
|
+
result[key.respond_to?(:to_sym) ? key.to_sym : key] = deep_symbolize_keys_in_object(value)
|
37
|
+
result
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def deep_symbolize_keys_in_object(value)
|
44
|
+
case value
|
45
|
+
when Hash
|
46
|
+
deep_symbolize_keys(value)
|
47
|
+
when Array
|
48
|
+
value.map { |e| deep_symbolize_keys_in_object(e) }
|
49
|
+
else
|
50
|
+
value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/i18n/version.rb
CHANGED
data/lib/i18n.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'concurrent/map'
|
4
|
+
require 'concurrent/hash'
|
2
5
|
|
3
6
|
require 'i18n/version'
|
7
|
+
require 'i18n/utils'
|
4
8
|
require 'i18n/exceptions'
|
5
9
|
require 'i18n/interpolate/ruby'
|
6
10
|
|
@@ -12,12 +16,40 @@ module I18n
|
|
12
16
|
autoload :Tests, 'i18n/tests'
|
13
17
|
autoload :Middleware, 'i18n/middleware'
|
14
18
|
|
15
|
-
RESERVED_KEYS = [
|
16
|
-
|
17
|
-
|
19
|
+
RESERVED_KEYS = %i[
|
20
|
+
cascade
|
21
|
+
deep_interpolation
|
22
|
+
skip_interpolation
|
23
|
+
default
|
24
|
+
exception_handler
|
25
|
+
fallback
|
26
|
+
fallback_in_progress
|
27
|
+
fallback_original_locale
|
28
|
+
format
|
29
|
+
object
|
30
|
+
raise
|
31
|
+
resolve
|
32
|
+
scope
|
33
|
+
separator
|
34
|
+
throw
|
35
|
+
]
|
36
|
+
EMPTY_HASH = {}.freeze
|
18
37
|
|
19
38
|
def self.new_double_nested_cache # :nodoc:
|
20
|
-
Concurrent::Map.new { |h,k| h[k] = Concurrent::Map.new }
|
39
|
+
Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Marks a key as reserved. Reserved keys are used internally,
|
43
|
+
# and can't also be used for interpolation. If you are using any
|
44
|
+
# extra keys as I18n options, you should call I18n.reserve_key
|
45
|
+
# before any I18n.translate (etc) calls are made.
|
46
|
+
def self.reserve_key(key)
|
47
|
+
RESERVED_KEYS << key.to_sym
|
48
|
+
@reserved_keys_pattern = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.reserved_keys_pattern # :nodoc:
|
52
|
+
@reserved_keys_pattern ||= /(?<!%)%\{(#{RESERVED_KEYS.join("|")})\}/
|
21
53
|
end
|
22
54
|
|
23
55
|
module Base
|
@@ -53,6 +85,13 @@ module I18n
|
|
53
85
|
config.backend.reload!
|
54
86
|
end
|
55
87
|
|
88
|
+
# Tells the backend to load translations now. Used in situations like the
|
89
|
+
# Rails production environment. Backends can implement whatever strategy
|
90
|
+
# is useful.
|
91
|
+
def eager_load!
|
92
|
+
config.backend.eager_load!
|
93
|
+
end
|
94
|
+
|
56
95
|
# Translates, pluralizes and interpolates a given key using a given locale,
|
57
96
|
# scope, and default, as well as interpolation values.
|
58
97
|
#
|
@@ -92,7 +131,7 @@ module I18n
|
|
92
131
|
# *PLURALIZATION*
|
93
132
|
#
|
94
133
|
# Translation data can contain pluralized translations. Pluralized translations
|
95
|
-
# are arrays of
|
134
|
+
# are arrays of singular/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
|
96
135
|
#
|
97
136
|
# Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
|
98
137
|
# pluralization rules. Other algorithms can be supported by custom backends.
|
@@ -123,7 +162,7 @@ module I18n
|
|
123
162
|
# or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
|
124
163
|
# I18n.t :foo, :default => [:bar, 'default']
|
125
164
|
#
|
126
|
-
#
|
165
|
+
# <b>BULK LOOKUP</b>
|
127
166
|
#
|
128
167
|
# This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
|
129
168
|
# I18n.t [:foo, :bar]
|
@@ -142,7 +181,7 @@ module I18n
|
|
142
181
|
# E.g. assuming the key <tt>:salutation</tt> resolves to:
|
143
182
|
# lambda { |key, options| options[:gender] == 'm' ? "Mr. #{options[:name]}" : "Mrs. #{options[:name]}" }
|
144
183
|
#
|
145
|
-
# Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith".
|
184
|
+
# Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith')</tt> will result in "Mrs. Smith".
|
146
185
|
#
|
147
186
|
# Note that the string returned by lambda will go through string interpolation too,
|
148
187
|
# so the following lambda would give the same result:
|
@@ -150,40 +189,85 @@ module I18n
|
|
150
189
|
#
|
151
190
|
# It is recommended to use/implement lambdas in an "idempotent" way. E.g. when
|
152
191
|
# a cache layer is put in front of I18n.translate it will generate a cache key
|
153
|
-
# from the argument values passed to #translate.
|
192
|
+
# from the argument values passed to #translate. Therefore your lambdas should
|
154
193
|
# always return the same translations/values per unique combination of argument
|
155
194
|
# values.
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
195
|
+
#
|
196
|
+
# <b>Ruby 2.7+ keyword arguments warning</b>
|
197
|
+
#
|
198
|
+
# This method uses keyword arguments.
|
199
|
+
# There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0
|
200
|
+
# The "hash" parameter must be passed as keyword argument.
|
201
|
+
#
|
202
|
+
# Good:
|
203
|
+
# I18n.t(:salutation, :gender => 'w', :name => 'Smith')
|
204
|
+
# I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' })
|
205
|
+
# I18n.t(:salutation, **any_hash)
|
206
|
+
#
|
207
|
+
# Bad:
|
208
|
+
# I18n.t(:salutation, { :gender => 'w', :name => 'Smith' })
|
209
|
+
# I18n.t(:salutation, any_hash)
|
210
|
+
#
|
211
|
+
def translate(key = nil, throw: false, raise: false, locale: nil, **options) # TODO deprecate :raise
|
212
|
+
locale ||= config.locale
|
213
|
+
raise Disabled.new('t') if locale == false
|
163
214
|
enforce_available_locales!(locale)
|
164
215
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
216
|
+
backend = config.backend
|
217
|
+
|
218
|
+
if key.is_a?(Array)
|
219
|
+
key.map do |k|
|
220
|
+
translate_key(k, throw, raise, locale, backend, options)
|
170
221
|
end
|
222
|
+
else
|
223
|
+
translate_key(key, throw, raise, locale, backend, options)
|
171
224
|
end
|
172
|
-
result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
|
173
225
|
end
|
174
226
|
alias :t :translate
|
175
227
|
|
176
228
|
# Wrapper for <tt>translate</tt> that adds <tt>:raise => true</tt>. With
|
177
229
|
# this option, if no translation is found, it will raise <tt>I18n::MissingTranslationData</tt>
|
178
|
-
def translate!(key, options
|
179
|
-
translate(key, options
|
230
|
+
def translate!(key, **options)
|
231
|
+
translate(key, **options, raise: true)
|
180
232
|
end
|
181
233
|
alias :t! :translate!
|
182
234
|
|
235
|
+
# Returns an array of interpolation keys for the given translation key
|
236
|
+
#
|
237
|
+
# *Examples*
|
238
|
+
#
|
239
|
+
# Suppose we have the following:
|
240
|
+
# I18n.t 'example.zero' == 'Zero interpolations'
|
241
|
+
# I18n.t 'example.one' == 'One interpolation %{foo}'
|
242
|
+
# I18n.t 'example.two' == 'Two interpolations %{foo} %{bar}'
|
243
|
+
# I18n.t 'example.three' == ['One %{foo}', 'Two %{bar}', 'Three %{baz}']
|
244
|
+
# I18n.t 'example.one', locale: :other == 'One interpolation %{baz}'
|
245
|
+
#
|
246
|
+
# Then we can expect the following results:
|
247
|
+
# I18n.interpolation_keys('example.zero') #=> []
|
248
|
+
# I18n.interpolation_keys('example.one') #=> ['foo']
|
249
|
+
# I18n.interpolation_keys('example.two') #=> ['foo', 'bar']
|
250
|
+
# I18n.interpolation_keys('example.three') #=> ['foo', 'bar', 'baz']
|
251
|
+
# I18n.interpolation_keys('one', scope: 'example', locale: :other) #=> ['baz']
|
252
|
+
# I18n.interpolation_keys('does-not-exist') #=> []
|
253
|
+
# I18n.interpolation_keys('example') #=> []
|
254
|
+
def interpolation_keys(key, **options)
|
255
|
+
raise I18n::ArgumentError if !key.is_a?(String) || key.empty?
|
256
|
+
|
257
|
+
return [] unless exists?(key, **options.slice(:locale, :scope))
|
258
|
+
|
259
|
+
translation = translate(key, **options.slice(:locale, :scope))
|
260
|
+
interpolation_keys_from_translation(translation)
|
261
|
+
.flatten.compact
|
262
|
+
end
|
263
|
+
|
183
264
|
# Returns true if a translation exists for a given key, otherwise returns false.
|
184
|
-
def exists?(key,
|
185
|
-
|
186
|
-
|
265
|
+
def exists?(key, _locale = nil, locale: _locale, **options)
|
266
|
+
locale ||= config.locale
|
267
|
+
raise Disabled.new('exists?') if locale == false
|
268
|
+
raise I18n::ArgumentError if (key.is_a?(String) && key.empty?) || key.nil?
|
269
|
+
|
270
|
+
config.backend.exists?(locale, key, options)
|
187
271
|
end
|
188
272
|
|
189
273
|
# Transliterates UTF-8 characters to ASCII. By default this method will
|
@@ -215,14 +299,14 @@ module I18n
|
|
215
299
|
#
|
216
300
|
# Setting a Hash using Ruby:
|
217
301
|
#
|
218
|
-
# store_translations(:de, :
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
302
|
+
# store_translations(:de, i18n: {
|
303
|
+
# transliterate: {
|
304
|
+
# rule: {
|
305
|
+
# 'ü' => 'ue',
|
306
|
+
# 'ö' => 'oe'
|
307
|
+
# }
|
308
|
+
# }
|
309
|
+
# })
|
226
310
|
#
|
227
311
|
# Setting a Proc:
|
228
312
|
#
|
@@ -237,37 +321,40 @@ module I18n
|
|
237
321
|
# I18n.transliterate("Jürgen") # => "Juergen"
|
238
322
|
# I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
|
239
323
|
# I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
|
240
|
-
def transliterate(
|
241
|
-
|
242
|
-
|
243
|
-
locale = options && options.delete(:locale) || config.locale
|
244
|
-
handling = options && (options.delete(:throw) && :throw || options.delete(:raise) && :raise)
|
245
|
-
replacement = options && options.delete(:replacement)
|
324
|
+
def transliterate(key, throw: false, raise: false, locale: nil, replacement: nil, **options)
|
325
|
+
locale ||= config.locale
|
326
|
+
raise Disabled.new('transliterate') if locale == false
|
246
327
|
enforce_available_locales!(locale)
|
328
|
+
|
247
329
|
config.backend.transliterate(locale, key, replacement)
|
248
330
|
rescue I18n::ArgumentError => exception
|
249
|
-
handle_exception(
|
331
|
+
handle_exception((throw && :throw || raise && :raise), exception, locale, key, options)
|
250
332
|
end
|
251
333
|
|
252
334
|
# Localizes certain objects, such as dates and numbers to local formatting.
|
253
|
-
def localize(object,
|
254
|
-
|
255
|
-
|
256
|
-
format = options.delete(:format) || :default
|
335
|
+
def localize(object, locale: nil, format: nil, **options)
|
336
|
+
locale ||= config.locale
|
337
|
+
raise Disabled.new('l') if locale == false
|
257
338
|
enforce_available_locales!(locale)
|
339
|
+
|
340
|
+
format ||= :default
|
258
341
|
config.backend.localize(locale, object, format, options)
|
259
342
|
end
|
260
343
|
alias :l :localize
|
261
344
|
|
262
345
|
# Executes block with given I18n.locale set.
|
263
346
|
def with_locale(tmp_locale = nil)
|
264
|
-
if tmp_locale
|
347
|
+
if tmp_locale == nil
|
348
|
+
yield
|
349
|
+
else
|
265
350
|
current_locale = self.locale
|
266
|
-
self.locale
|
351
|
+
self.locale = tmp_locale
|
352
|
+
begin
|
353
|
+
yield
|
354
|
+
ensure
|
355
|
+
self.locale = current_locale
|
356
|
+
end
|
267
357
|
end
|
268
|
-
yield
|
269
|
-
ensure
|
270
|
-
self.locale = current_locale if tmp_locale
|
271
358
|
end
|
272
359
|
|
273
360
|
# Merges the given locale, key and scope into a single array of keys.
|
@@ -276,11 +363,11 @@ module I18n
|
|
276
363
|
def normalize_keys(locale, key, scope, separator = nil)
|
277
364
|
separator ||= I18n.default_separator
|
278
365
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
366
|
+
[
|
367
|
+
*normalize_key(locale, separator),
|
368
|
+
*normalize_key(scope, separator),
|
369
|
+
*normalize_key(key, separator)
|
370
|
+
]
|
284
371
|
end
|
285
372
|
|
286
373
|
# Returns true when the passed locale, which can be either a String or a
|
@@ -291,7 +378,7 @@ module I18n
|
|
291
378
|
|
292
379
|
# Raises an InvalidLocale exception when the passed locale is not available.
|
293
380
|
def enforce_available_locales!(locale)
|
294
|
-
if config.enforce_available_locales
|
381
|
+
if locale != false && config.enforce_available_locales
|
295
382
|
raise I18n::InvalidLocale.new(locale) if !locale_available?(locale)
|
296
383
|
end
|
297
384
|
end
|
@@ -302,6 +389,18 @@ module I18n
|
|
302
389
|
|
303
390
|
private
|
304
391
|
|
392
|
+
def translate_key(key, throw, raise, locale, backend, options)
|
393
|
+
result = catch(:exception) do
|
394
|
+
backend.translate(locale, key, options)
|
395
|
+
end
|
396
|
+
|
397
|
+
if result.is_a?(MissingTranslation)
|
398
|
+
handle_exception((throw && :throw || raise && :raise), result, locale, key, options)
|
399
|
+
else
|
400
|
+
result
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
305
404
|
# Any exceptions thrown in translate will be sent to the @@exception_handler
|
306
405
|
# which can be a Symbol, a Proc or any other Object unless they're forced to
|
307
406
|
# be raised or thrown (MissingTranslation).
|
@@ -342,14 +441,36 @@ module I18n
|
|
342
441
|
@@normalized_key_cache[separator][key] ||=
|
343
442
|
case key
|
344
443
|
when Array
|
345
|
-
key.
|
444
|
+
key.flat_map { |k| normalize_key(k, separator) }
|
346
445
|
else
|
347
446
|
keys = key.to_s.split(separator)
|
348
447
|
keys.delete('')
|
349
|
-
keys.map!
|
448
|
+
keys.map! do |k|
|
449
|
+
case k
|
450
|
+
when /\A[-+]?([1-9]\d*|0)\z/ # integer
|
451
|
+
k.to_i
|
452
|
+
when 'true'
|
453
|
+
true
|
454
|
+
when 'false'
|
455
|
+
false
|
456
|
+
else
|
457
|
+
k.to_sym
|
458
|
+
end
|
459
|
+
end
|
350
460
|
keys
|
351
461
|
end
|
352
462
|
end
|
463
|
+
|
464
|
+
def interpolation_keys_from_translation(translation)
|
465
|
+
case translation
|
466
|
+
when ::String
|
467
|
+
translation.scan(Regexp.union(I18n.config.interpolation_patterns))
|
468
|
+
when ::Array
|
469
|
+
translation.map { |element| interpolation_keys_from_translation(element) }
|
470
|
+
else
|
471
|
+
[]
|
472
|
+
end
|
473
|
+
end
|
353
474
|
end
|
354
475
|
|
355
476
|
extend Base
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -10,10 +10,10 @@ authors:
|
|
10
10
|
- Stephan Soller
|
11
11
|
- Saimon Moore
|
12
12
|
- Ryan Bigg
|
13
|
-
autorequire:
|
13
|
+
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2025-01-19 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: concurrent-ruby
|
@@ -37,17 +37,11 @@ extra_rdoc_files: []
|
|
37
37
|
files:
|
38
38
|
- MIT-LICENSE
|
39
39
|
- README.md
|
40
|
-
- gemfiles/Gemfile.rails-3.2.x
|
41
|
-
- gemfiles/Gemfile.rails-4.0.x
|
42
|
-
- gemfiles/Gemfile.rails-4.1.x
|
43
|
-
- gemfiles/Gemfile.rails-4.2.x
|
44
|
-
- gemfiles/Gemfile.rails-5.0.x
|
45
|
-
- gemfiles/Gemfile.rails-5.1.x
|
46
|
-
- gemfiles/Gemfile.rails-master
|
47
40
|
- lib/i18n.rb
|
48
41
|
- lib/i18n/backend.rb
|
49
42
|
- lib/i18n/backend/base.rb
|
50
43
|
- lib/i18n/backend/cache.rb
|
44
|
+
- lib/i18n/backend/cache_file.rb
|
51
45
|
- lib/i18n/backend/cascade.rb
|
52
46
|
- lib/i18n/backend/chain.rb
|
53
47
|
- lib/i18n/backend/fallbacks.rb
|
@@ -55,15 +49,13 @@ files:
|
|
55
49
|
- lib/i18n/backend/gettext.rb
|
56
50
|
- lib/i18n/backend/interpolation_compiler.rb
|
57
51
|
- lib/i18n/backend/key_value.rb
|
52
|
+
- lib/i18n/backend/lazy_loadable.rb
|
58
53
|
- lib/i18n/backend/memoize.rb
|
59
54
|
- lib/i18n/backend/metadata.rb
|
60
55
|
- lib/i18n/backend/pluralization.rb
|
61
56
|
- lib/i18n/backend/simple.rb
|
62
57
|
- lib/i18n/backend/transliterator.rb
|
63
58
|
- lib/i18n/config.rb
|
64
|
-
- lib/i18n/core_ext/hash.rb
|
65
|
-
- lib/i18n/core_ext/kernel/suppress_warnings.rb
|
66
|
-
- lib/i18n/core_ext/string/interpolate.rb
|
67
59
|
- lib/i18n/exceptions.rb
|
68
60
|
- lib/i18n/gettext.rb
|
69
61
|
- lib/i18n/gettext/helpers.rb
|
@@ -89,53 +81,17 @@ files:
|
|
89
81
|
- lib/i18n/tests/lookup.rb
|
90
82
|
- lib/i18n/tests/pluralization.rb
|
91
83
|
- lib/i18n/tests/procs.rb
|
84
|
+
- lib/i18n/utils.rb
|
92
85
|
- lib/i18n/version.rb
|
93
|
-
|
94
|
-
- test/api/cascade_test.rb
|
95
|
-
- test/api/chain_test.rb
|
96
|
-
- test/api/fallbacks_test.rb
|
97
|
-
- test/api/key_value_test.rb
|
98
|
-
- test/api/memoize_test.rb
|
99
|
-
- test/api/override_test.rb
|
100
|
-
- test/api/pluralization_test.rb
|
101
|
-
- test/api/simple_test.rb
|
102
|
-
- test/backend/cache_test.rb
|
103
|
-
- test/backend/cascade_test.rb
|
104
|
-
- test/backend/chain_test.rb
|
105
|
-
- test/backend/exceptions_test.rb
|
106
|
-
- test/backend/fallbacks_test.rb
|
107
|
-
- test/backend/interpolation_compiler_test.rb
|
108
|
-
- test/backend/key_value_test.rb
|
109
|
-
- test/backend/memoize_test.rb
|
110
|
-
- test/backend/metadata_test.rb
|
111
|
-
- test/backend/pluralization_test.rb
|
112
|
-
- test/backend/simple_test.rb
|
113
|
-
- test/backend/transliterator_test.rb
|
114
|
-
- test/core_ext/hash_test.rb
|
115
|
-
- test/gettext/api_test.rb
|
116
|
-
- test/gettext/backend_test.rb
|
117
|
-
- test/i18n/exceptions_test.rb
|
118
|
-
- test/i18n/gettext_plural_keys_test.rb
|
119
|
-
- test/i18n/interpolate_test.rb
|
120
|
-
- test/i18n/load_path_test.rb
|
121
|
-
- test/i18n/middleware_test.rb
|
122
|
-
- test/i18n_test.rb
|
123
|
-
- test/locale/fallbacks_test.rb
|
124
|
-
- test/locale/tag/rfc4646_test.rb
|
125
|
-
- test/locale/tag/simple_test.rb
|
126
|
-
- test/run_all.rb
|
127
|
-
- test/test_data/locales/de.po
|
128
|
-
- test/test_data/locales/en.rb
|
129
|
-
- test/test_data/locales/en.yml
|
130
|
-
- test/test_data/locales/invalid/empty.yml
|
131
|
-
- test/test_data/locales/invalid/syntax.yml
|
132
|
-
- test/test_data/locales/plurals.rb
|
133
|
-
- test/test_helper.rb
|
134
|
-
homepage: http://github.com/svenfuchs/i18n
|
86
|
+
homepage: https://github.com/ruby-i18n/i18n
|
135
87
|
licenses:
|
136
88
|
- MIT
|
137
|
-
metadata:
|
138
|
-
|
89
|
+
metadata:
|
90
|
+
bug_tracker_uri: https://github.com/ruby-i18n/i18n/issues
|
91
|
+
changelog_uri: https://github.com/ruby-i18n/i18n/releases
|
92
|
+
documentation_uri: https://guides.rubyonrails.org/i18n.html
|
93
|
+
source_code_uri: https://github.com/ruby-i18n/i18n
|
94
|
+
post_install_message:
|
139
95
|
rdoc_options: []
|
140
96
|
require_paths:
|
141
97
|
- lib
|
@@ -143,16 +99,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
99
|
requirements:
|
144
100
|
- - ">="
|
145
101
|
- !ruby/object:Gem::Version
|
146
|
-
version: 2.
|
102
|
+
version: 2.3.0
|
147
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
104
|
requirements:
|
149
105
|
- - ">="
|
150
106
|
- !ruby/object:Gem::Version
|
151
107
|
version: 1.3.5
|
152
108
|
requirements: []
|
153
|
-
|
154
|
-
|
155
|
-
signing_key:
|
109
|
+
rubygems_version: 3.5.23
|
110
|
+
signing_key:
|
156
111
|
specification_version: 4
|
157
112
|
summary: New wave Internationalization support for Ruby
|
158
113
|
test_files: []
|
data/lib/i18n/core_ext/hash.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
class Hash
|
2
|
-
def slice(*keep_keys)
|
3
|
-
h = {}
|
4
|
-
keep_keys.each { |key| h[key] = fetch(key) if has_key?(key) }
|
5
|
-
h
|
6
|
-
end unless Hash.method_defined?(:slice)
|
7
|
-
|
8
|
-
def except(*less_keys)
|
9
|
-
slice(*keys - less_keys)
|
10
|
-
end unless Hash.method_defined?(:except)
|
11
|
-
|
12
|
-
def deep_symbolize_keys
|
13
|
-
inject({}) { |result, (key, value)|
|
14
|
-
value = value.deep_symbolize_keys if value.is_a?(Hash)
|
15
|
-
result[(key.to_sym rescue key) || key] = value
|
16
|
-
result
|
17
|
-
}
|
18
|
-
end unless Hash.method_defined?(:deep_symbolize_keys)
|
19
|
-
|
20
|
-
# deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
21
|
-
MERGER = proc do |key, v1, v2|
|
22
|
-
Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
|
23
|
-
end
|
24
|
-
|
25
|
-
def deep_merge!(data)
|
26
|
-
merge!(data, &MERGER)
|
27
|
-
end unless Hash.method_defined?(:deep_merge!)
|
28
|
-
end
|
29
|
-
|