i18n 1.14.5 → 1.14.8
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/lib/i18n/backend/base.rb +11 -3
- data/lib/i18n/backend/fallbacks.rb +5 -1
- data/lib/i18n/backend/interpolation_compiler.rb +1 -0
- data/lib/i18n/backend/simple.rb +8 -8
- data/lib/i18n/exceptions.rb +0 -2
- data/lib/i18n/middleware.rb +1 -1
- data/lib/i18n/tests/defaults.rb +7 -0
- data/lib/i18n/tests/interpolation.rb +3 -3
- data/lib/i18n/tests/localization/procs.rb +2 -2
- data/lib/i18n/tests/lookup.rb +6 -0
- data/lib/i18n/tests/procs.rb +12 -7
- data/lib/i18n/version.rb +1 -1
- data/lib/i18n.rb +9 -6
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: edf1a48f0dd110066260f4d93cd2af16e73e9f91845a16126794d4c9af5b664c
|
|
4
|
+
data.tar.gz: 36a488fcbbaefdabb42e1a6f42af534fa36f640de5674d31a92407d6dfd1835d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82897d5266dfb62379930d6f94346dc0e62c14e619995e3933dc6339d0dd6d06d4b491449d1f4eb43128de995e3d9837624e4132b7b506455e0169dece108b7f
|
|
7
|
+
data.tar.gz: 8938b0f8d862e989f7427ccb2299722914bd485af9afff24bf0bda6cd8f438dc750cacd8c85d45292787f2e78438ead7c7533d6c696f5d5b9fc7109535a48ee4
|
data/lib/i18n/backend/base.rb
CHANGED
|
@@ -54,8 +54,9 @@ module I18n
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
deep_interpolation = options[:deep_interpolation]
|
|
57
|
+
skip_interpolation = options[:skip_interpolation]
|
|
57
58
|
values = Utils.except(options, *RESERVED_KEYS) unless options.empty?
|
|
58
|
-
if values && !values.empty?
|
|
59
|
+
if !skip_interpolation && values && !values.empty?
|
|
59
60
|
entry = if deep_interpolation
|
|
60
61
|
deep_interpolate(locale, entry, values)
|
|
61
62
|
else
|
|
@@ -151,7 +152,14 @@ module I18n
|
|
|
151
152
|
result = catch(:exception) do
|
|
152
153
|
case subject
|
|
153
154
|
when Symbol
|
|
154
|
-
I18n.translate(
|
|
155
|
+
I18n.translate(
|
|
156
|
+
subject,
|
|
157
|
+
**options.merge(
|
|
158
|
+
:locale => locale,
|
|
159
|
+
:throw => true,
|
|
160
|
+
:skip_interpolation => true
|
|
161
|
+
)
|
|
162
|
+
)
|
|
155
163
|
when Proc
|
|
156
164
|
date_or_time = options.delete(:object) || object
|
|
157
165
|
resolve(locale, object, subject.call(date_or_time, **options))
|
|
@@ -244,7 +252,7 @@ module I18n
|
|
|
244
252
|
# Loads a plain Ruby translations file. eval'ing the file must yield
|
|
245
253
|
# a Hash containing translation data with locales as toplevel keys.
|
|
246
254
|
def load_rb(filename)
|
|
247
|
-
translations = eval(IO.read(filename), binding, filename)
|
|
255
|
+
translations = eval(IO.read(filename), binding, filename.to_s)
|
|
248
256
|
[translations, false]
|
|
249
257
|
end
|
|
250
258
|
|
|
@@ -71,7 +71,11 @@ module I18n
|
|
|
71
71
|
|
|
72
72
|
case subject
|
|
73
73
|
when Symbol
|
|
74
|
-
I18n.translate(subject, **options.merge(
|
|
74
|
+
I18n.translate(subject, **options.merge(
|
|
75
|
+
:locale => options[:fallback_original_locale],
|
|
76
|
+
:throw => true,
|
|
77
|
+
:skip_interpolation => true
|
|
78
|
+
))
|
|
75
79
|
when Proc
|
|
76
80
|
date_or_time = options.delete(:object) || object
|
|
77
81
|
resolve_entry(options[:fallback_original_locale], object, subject.call(date_or_time, **options))
|
data/lib/i18n/backend/simple.rb
CHANGED
|
@@ -10,14 +10,14 @@ module I18n
|
|
|
10
10
|
# The implementation is provided by a Implementation module allowing to easily
|
|
11
11
|
# extend Simple backend's behavior by including modules. E.g.:
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
13
|
+
# module I18n::Backend::Pluralization
|
|
14
|
+
# def pluralize(*args)
|
|
15
|
+
# # extended pluralization logic
|
|
16
|
+
# super
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# I18n::Backend::Simple.include(I18n::Backend::Pluralization)
|
|
21
21
|
class Simple
|
|
22
22
|
module Implementation
|
|
23
23
|
include Base
|
data/lib/i18n/exceptions.rb
CHANGED
data/lib/i18n/middleware.rb
CHANGED
data/lib/i18n/tests/defaults.rb
CHANGED
|
@@ -47,6 +47,13 @@ module I18n
|
|
|
47
47
|
I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' })
|
|
48
48
|
assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|')
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
# Addresses issue: #599
|
|
52
|
+
test "defaults: only interpolates once when resolving defaults" do
|
|
53
|
+
I18n.backend.store_translations(:en, :greeting => 'hey %{name}')
|
|
54
|
+
assert_equal 'hey %{dont_interpolate_me}',
|
|
55
|
+
I18n.t(:does_not_exist, :name => '%{dont_interpolate_me}', default: [:greeting])
|
|
56
|
+
end
|
|
50
57
|
end
|
|
51
58
|
end
|
|
52
59
|
end
|
|
@@ -89,14 +89,14 @@ module I18n
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
test "interpolation: ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do
|
|
92
|
-
I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.force_encoding(
|
|
92
|
+
I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.dup.force_encoding(Encoding::US_ASCII))
|
|
93
93
|
result = I18n.t 'encoding', :who => "måmmå miå"
|
|
94
94
|
assert_equal Encoding::UTF_8, result.encoding
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
test "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" do
|
|
98
98
|
I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}'
|
|
99
|
-
result = I18n.t 'encoding', :what => 'let me go'.force_encoding(
|
|
99
|
+
result = I18n.t 'encoding', :what => 'let me go'.dup.force_encoding(Encoding::US_ASCII)
|
|
100
100
|
assert_equal Encoding::UTF_8, result.encoding
|
|
101
101
|
end
|
|
102
102
|
|
|
@@ -172,7 +172,7 @@ module I18n
|
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
def euc_jp(string)
|
|
175
|
-
string.encode
|
|
175
|
+
string.encode(Encoding::EUC_JP)
|
|
176
176
|
end
|
|
177
177
|
|
|
178
178
|
def interpolate(*args)
|
|
@@ -34,7 +34,7 @@ module I18n
|
|
|
34
34
|
test "localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
|
35
35
|
setup_time_proc_translations
|
|
36
36
|
date = ::Date.new(2008, 3, 1)
|
|
37
|
-
assert_equal
|
|
37
|
+
assert_equal %|[Sat, 01 Mar 2008, #{{:foo=>"foo"}}]|, I18n.l(date, :format => :proc, :foo => 'foo', :locale => :ru)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object" do
|
|
@@ -46,7 +46,7 @@ module I18n
|
|
|
46
46
|
test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
|
47
47
|
setup_time_proc_translations
|
|
48
48
|
datetime = ::DateTime.new(2008, 3, 1, 6)
|
|
49
|
-
assert_equal
|
|
49
|
+
assert_equal %|[Sat, 01 Mar 2008 06:00:00 +00:00, #{{:foo=>"foo"}}]|, I18n.l(datetime, :format => :proc, :foo => 'foo', :locale => :ru)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do
|
data/lib/i18n/tests/lookup.rb
CHANGED
|
@@ -76,6 +76,12 @@ module I18n
|
|
|
76
76
|
test "lookup: a resulting Hash is not frozen" do
|
|
77
77
|
assert !I18n.t(:hash).frozen?
|
|
78
78
|
end
|
|
79
|
+
|
|
80
|
+
# Addresses issue: #599
|
|
81
|
+
test "lookup: only interpolates once when resolving symbols" do
|
|
82
|
+
I18n.backend.store_translations(:en, foo: :bar, bar: '%{value}')
|
|
83
|
+
assert_equal '%{dont_interpolate_me}', I18n.t(:foo, value: '%{dont_interpolate_me}')
|
|
84
|
+
end
|
|
79
85
|
end
|
|
80
86
|
end
|
|
81
87
|
end
|
data/lib/i18n/tests/procs.rb
CHANGED
|
@@ -5,34 +5,38 @@ module I18n
|
|
|
5
5
|
module Procs
|
|
6
6
|
test "lookup: given a translation is a proc it calls the proc with the key and interpolation values" do
|
|
7
7
|
I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) })
|
|
8
|
-
assert_equal
|
|
8
|
+
assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(:a_lambda, :foo => 'foo')
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
test "lookup: given a translation is a proc it passes the interpolation values as keyword arguments" do
|
|
12
12
|
I18n.backend.store_translations(:en, :a_lambda => lambda { |key, foo:, **| I18n::Tests::Procs.filter_args(key, foo: foo) })
|
|
13
|
-
assert_equal
|
|
13
|
+
assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(:a_lambda, :foo => 'foo')
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
test "defaults: given a default is a Proc it calls it with the key and interpolation values" do
|
|
17
17
|
proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
|
18
|
-
assert_equal
|
|
18
|
+
assert_equal %|[nil, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => proc, :foo => 'foo')
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
test "defaults: given a default is a key that resolves to a Proc it calls it with the key and interpolation values" do
|
|
22
22
|
the_lambda = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
|
23
23
|
I18n.backend.store_translations(:en, :a_lambda => the_lambda)
|
|
24
|
-
assert_equal
|
|
25
|
-
assert_equal
|
|
24
|
+
assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => :a_lambda, :foo => 'foo')
|
|
25
|
+
assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => [nil, :a_lambda], :foo => 'foo')
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
test "interpolation: given an interpolation value is a lambda it calls it with key and values before interpolating it" do
|
|
29
29
|
proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
|
30
|
-
|
|
30
|
+
if RUBY_VERSION < "3.4"
|
|
31
|
+
assert_match %r(\[\{:foo=>#<Proc.*>\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc)
|
|
32
|
+
else
|
|
33
|
+
assert_match %r(\[\{foo: #<Proc.*>\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc)
|
|
34
|
+
end
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
test "interpolation: given a key resolves to a Proc that returns a string then interpolation still works" do
|
|
34
38
|
proc = lambda { |*args| "%{foo}: " + I18n::Tests::Procs.filter_args(*args) }
|
|
35
|
-
assert_equal
|
|
39
|
+
assert_equal %|foo: [nil, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => proc, :foo => 'foo')
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
test "pluralization: given a key resolves to a Proc that returns valid data then pluralization still works" do
|
|
@@ -57,6 +61,7 @@ module I18n
|
|
|
57
61
|
if arg.is_a?(Hash)
|
|
58
62
|
arg.delete(:fallback_in_progress)
|
|
59
63
|
arg.delete(:fallback_original_locale)
|
|
64
|
+
arg.delete(:skip_interpolation)
|
|
60
65
|
end
|
|
61
66
|
arg
|
|
62
67
|
end.inspect
|
data/lib/i18n/version.rb
CHANGED
data/lib/i18n.rb
CHANGED
|
@@ -19,6 +19,7 @@ module I18n
|
|
|
19
19
|
RESERVED_KEYS = %i[
|
|
20
20
|
cascade
|
|
21
21
|
deep_interpolation
|
|
22
|
+
skip_interpolation
|
|
22
23
|
default
|
|
23
24
|
exception_handler
|
|
24
25
|
fallback
|
|
@@ -54,12 +55,13 @@ module I18n
|
|
|
54
55
|
module Base
|
|
55
56
|
# Gets I18n configuration object.
|
|
56
57
|
def config
|
|
57
|
-
Thread.current
|
|
58
|
+
Thread.current.thread_variable_get(:i18n_config) ||
|
|
59
|
+
Thread.current.thread_variable_set(:i18n_config, I18n::Config.new)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
# Sets I18n configuration object.
|
|
61
63
|
def config=(value)
|
|
62
|
-
Thread.current
|
|
64
|
+
Thread.current.thread_variable_set(:i18n_config, value)
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
# Write methods which delegates to the configuration object
|
|
@@ -161,7 +163,7 @@ module I18n
|
|
|
161
163
|
# or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
|
|
162
164
|
# I18n.t :foo, :default => [:bar, 'default']
|
|
163
165
|
#
|
|
164
|
-
#
|
|
166
|
+
# <b>BULK LOOKUP</b>
|
|
165
167
|
#
|
|
166
168
|
# This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
|
|
167
169
|
# I18n.t [:foo, :bar]
|
|
@@ -180,7 +182,7 @@ module I18n
|
|
|
180
182
|
# E.g. assuming the key <tt>:salutation</tt> resolves to:
|
|
181
183
|
# lambda { |key, options| options[:gender] == 'm' ? "Mr. #{options[:name]}" : "Mrs. #{options[:name]}" }
|
|
182
184
|
#
|
|
183
|
-
# Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith".
|
|
185
|
+
# Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith')</tt> will result in "Mrs. Smith".
|
|
184
186
|
#
|
|
185
187
|
# Note that the string returned by lambda will go through string interpolation too,
|
|
186
188
|
# so the following lambda would give the same result:
|
|
@@ -192,7 +194,7 @@ module I18n
|
|
|
192
194
|
# always return the same translations/values per unique combination of argument
|
|
193
195
|
# values.
|
|
194
196
|
#
|
|
195
|
-
#
|
|
197
|
+
# <b>Ruby 2.7+ keyword arguments warning</b>
|
|
196
198
|
#
|
|
197
199
|
# This method uses keyword arguments.
|
|
198
200
|
# There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0
|
|
@@ -264,7 +266,8 @@ module I18n
|
|
|
264
266
|
def exists?(key, _locale = nil, locale: _locale, **options)
|
|
265
267
|
locale ||= config.locale
|
|
266
268
|
raise Disabled.new('exists?') if locale == false
|
|
267
|
-
raise I18n::ArgumentError if key.is_a?(String) && key.empty?
|
|
269
|
+
raise I18n::ArgumentError if (key.is_a?(String) && key.empty?) || key.nil?
|
|
270
|
+
|
|
268
271
|
config.backend.exists?(locale, key, options)
|
|
269
272
|
end
|
|
270
273
|
|
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.14.
|
|
4
|
+
version: 1.14.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sven Fuchs
|
|
@@ -13,7 +13,7 @@ authors:
|
|
|
13
13
|
autorequire:
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date:
|
|
16
|
+
date: 2025-12-21 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: concurrent-ruby
|
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
107
|
version: 1.3.5
|
|
108
108
|
requirements: []
|
|
109
|
-
rubygems_version: 3.5.
|
|
109
|
+
rubygems_version: 3.5.23
|
|
110
110
|
signing_key:
|
|
111
111
|
specification_version: 4
|
|
112
112
|
summary: New wave Internationalization support for Ruby
|