i18n 1.8.2 → 1.8.3
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 +19 -22
- data/lib/i18n.rb +3 -3
- data/lib/i18n/backend/base.rb +3 -2
- data/lib/i18n/backend/chain.rb +3 -4
- data/lib/i18n/backend/fallbacks.rb +13 -2
- data/lib/i18n/backend/flatten.rb +8 -5
- data/lib/i18n/core_ext/hash.rb +17 -5
- data/lib/i18n/locale/fallbacks.rb +6 -4
- data/lib/i18n/locale/tag/parents.rb +8 -6
- data/lib/i18n/locale/tag/simple.rb +1 -1
- data/lib/i18n/tests/localization/procs.rb +6 -5
- data/lib/i18n/tests/procs.rb +5 -0
- data/lib/i18n/version.rb +1 -1
- 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: 461ee8866033d12fb5dd2daaa85703916b83ba58c225afd5bfe31e30c3231aa6
|
4
|
+
data.tar.gz: 9bd10034e9629c3fb72c07974fef0b069047b269dbab165ecbd5b8c38c9c5567
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: feb783a73598b1ab9e319f5569d71b14c061816bdb8e7d887262fed6531ec0a3c77afa36a4257080bbc7a1ec5239963a08b2f37a3dd449db82f9e402c5f57fbc
|
7
|
+
data.tar.gz: fdb2f914e53484a8cf925b71de1004a4d0c1bfa3da4b7d50bd14fcda1ab036ae12d773e692cbf85ade5e78906af24fcc05b22156e280a4615e26430f8929eb75
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://github.com/ruby-i18n/i18n/actions?query=workflow%3ARuby)
|
4
4
|
|
5
|
-
Ruby
|
5
|
+
Ruby internationalization and localization (i18n) solution.
|
6
6
|
|
7
7
|
Currently maintained by @radar.
|
8
8
|
|
@@ -12,7 +12,7 @@ Currently maintained by @radar.
|
|
12
12
|
|
13
13
|
You will most commonly use this library within a Rails app.
|
14
14
|
|
15
|
-
[See the Rails Guide](
|
15
|
+
[See the Rails Guide](https://guides.rubyonrails.org/i18n.html) for an example of its usage.
|
16
16
|
|
17
17
|
### Ruby (without Rails)
|
18
18
|
|
@@ -51,16 +51,16 @@ I18n.t(:test) # => "Dies ist ein Test"
|
|
51
51
|
|
52
52
|
## Features
|
53
53
|
|
54
|
-
*
|
55
|
-
*
|
56
|
-
*
|
57
|
-
*
|
58
|
-
*
|
59
|
-
*
|
60
|
-
*
|
61
|
-
*
|
62
|
-
*
|
63
|
-
*
|
54
|
+
* Translation and localization
|
55
|
+
* Interpolation of values to translations
|
56
|
+
* Pluralization (CLDR compatible)
|
57
|
+
* Customizable transliteration to ASCII
|
58
|
+
* Flexible defaults
|
59
|
+
* Bulk lookup
|
60
|
+
* Lambdas as translation data
|
61
|
+
* Custom key/scope separator
|
62
|
+
* Custom exception handlers
|
63
|
+
* Extensible architecture with a swappable backend
|
64
64
|
|
65
65
|
## Pluggable Features
|
66
66
|
|
@@ -106,19 +106,16 @@ follow the usual test setup and should be easy to grok.
|
|
106
106
|
|
107
107
|
## More Documentation
|
108
108
|
|
109
|
-
Additional documentation can be found here: https://github.com/
|
110
|
-
|
111
|
-
## Authors
|
112
|
-
|
113
|
-
* [Sven Fuchs](http://www.artweb-design.de)
|
114
|
-
* [Joshua Harvey](http://www.workingwithrails.com/person/759-joshua-harvey)
|
115
|
-
* [Stephan Soller](http://www.arkanis-development.de)
|
116
|
-
* [Saimon Moore](http://saimonmoore.net)
|
117
|
-
* [Matt Aimonetti](https://matt.aimonetti.net/)
|
109
|
+
Additional documentation can be found here: https://github.com/ruby-i18n/i18n/wiki
|
118
110
|
|
119
111
|
## Contributors
|
120
112
|
|
121
|
-
|
113
|
+
* @radar
|
114
|
+
* @carlosantoniodasilva
|
115
|
+
* @josevalim
|
116
|
+
* @knapo
|
117
|
+
* @tigrish
|
118
|
+
* [and many more](https://github.com/ruby-i18n/i18n/graphs/contributors)
|
122
119
|
|
123
120
|
## License
|
124
121
|
|
data/lib/i18n.rb
CHANGED
@@ -223,11 +223,11 @@ module I18n
|
|
223
223
|
alias :t! :translate!
|
224
224
|
|
225
225
|
# Returns true if a translation exists for a given key, otherwise returns false.
|
226
|
-
def exists?(key, _locale = nil, locale: _locale)
|
226
|
+
def exists?(key, _locale = nil, locale: _locale, **options)
|
227
227
|
locale ||= config.locale
|
228
228
|
raise Disabled.new('exists?') if locale == false
|
229
229
|
raise I18n::ArgumentError if key.is_a?(String) && key.empty?
|
230
|
-
config.backend.exists?(locale, key)
|
230
|
+
config.backend.exists?(locale, key, options)
|
231
231
|
end
|
232
232
|
|
233
233
|
# Transliterates UTF-8 characters to ASCII. By default this method will
|
@@ -389,7 +389,7 @@ module I18n
|
|
389
389
|
@@normalized_key_cache[separator][key] ||=
|
390
390
|
case key
|
391
391
|
when Array
|
392
|
-
key.
|
392
|
+
key.flat_map { |k| normalize_key(k, separator) }
|
393
393
|
else
|
394
394
|
keys = key.to_s.split(separator)
|
395
395
|
keys.delete('')
|
data/lib/i18n/backend/base.rb
CHANGED
@@ -64,7 +64,7 @@ module I18n
|
|
64
64
|
entry
|
65
65
|
end
|
66
66
|
|
67
|
-
def exists?(locale, key)
|
67
|
+
def exists?(locale, key, options = EMPTY_HASH)
|
68
68
|
lookup(locale, key) != nil
|
69
69
|
end
|
70
70
|
|
@@ -146,7 +146,7 @@ module I18n
|
|
146
146
|
I18n.translate(subject, **options.merge(:locale => locale, :throw => true))
|
147
147
|
when Proc
|
148
148
|
date_or_time = options.delete(:object) || object
|
149
|
-
resolve(locale, object, subject.call(date_or_time, options))
|
149
|
+
resolve(locale, object, subject.call(date_or_time, **options))
|
150
150
|
else
|
151
151
|
subject
|
152
152
|
end
|
@@ -163,6 +163,7 @@ module I18n
|
|
163
163
|
# not standard with regards to the CLDR pluralization rules.
|
164
164
|
# Other backends can implement more flexible or complex pluralization rules.
|
165
165
|
def pluralize(locale, entry, count)
|
166
|
+
entry = entry.reject { |k, _v| k == :attributes } if entry.is_a?(Hash)
|
166
167
|
return entry unless entry.is_a?(Hash) && count && entry.values.none? { |v| v.is_a?(Hash) }
|
167
168
|
|
168
169
|
key = pluralization_key(entry, count)
|
data/lib/i18n/backend/chain.rb
CHANGED
@@ -73,9 +73,9 @@ module I18n
|
|
73
73
|
throw(:exception, I18n::MissingTranslation.new(locale, key, options))
|
74
74
|
end
|
75
75
|
|
76
|
-
def exists?(locale, key)
|
76
|
+
def exists?(locale, key, options = EMPTY_HASH)
|
77
77
|
backends.any? do |backend|
|
78
|
-
backend.exists?(locale, key)
|
78
|
+
backend.exists?(locale, key, options)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -101,8 +101,7 @@ module I18n
|
|
101
101
|
init_translations unless initialized?
|
102
102
|
translations
|
103
103
|
end
|
104
|
-
|
105
|
-
memo.deep_merge!(partial_translations)
|
104
|
+
memo.deep_merge!(partial_translations) { |_, a, b| b || a }
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
@@ -46,7 +46,10 @@ module I18n
|
|
46
46
|
begin
|
47
47
|
catch(:exception) do
|
48
48
|
result = super(fallback, key, fallback_options)
|
49
|
-
|
49
|
+
unless result.nil?
|
50
|
+
on_fallback(locale, fallback, key, options) if locale != fallback
|
51
|
+
return result
|
52
|
+
end
|
50
53
|
end
|
51
54
|
rescue I18n::InvalidLocale
|
52
55
|
# we do nothing when the locale is invalid, as this is a fallback anyways.
|
@@ -68,7 +71,8 @@ module I18n
|
|
68
71
|
return first_non_symbol_default
|
69
72
|
end
|
70
73
|
|
71
|
-
def exists?(locale, key)
|
74
|
+
def exists?(locale, key, options = EMPTY_HASH)
|
75
|
+
return super unless options.fetch(:fallback, true)
|
72
76
|
I18n.fallbacks[locale].each do |fallback|
|
73
77
|
begin
|
74
78
|
return true if super(fallback, key)
|
@@ -79,6 +83,13 @@ module I18n
|
|
79
83
|
|
80
84
|
false
|
81
85
|
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# Overwrite on_fallback to add specified logic when the fallback succeeds.
|
90
|
+
def on_fallback(_original_locale, _fallback_locale, _key, _optoins)
|
91
|
+
nil
|
92
|
+
end
|
82
93
|
end
|
83
94
|
end
|
84
95
|
end
|
data/lib/i18n/backend/flatten.rb
CHANGED
@@ -18,14 +18,17 @@ module I18n
|
|
18
18
|
# and creates way less objects than the one at I18n.normalize_keys.
|
19
19
|
# It also handles escaping the translation keys.
|
20
20
|
def self.normalize_flat_keys(locale, key, scope, separator)
|
21
|
-
keys = [scope, key]
|
21
|
+
keys = [scope, key]
|
22
|
+
keys.flatten!
|
23
|
+
keys.compact!
|
24
|
+
|
22
25
|
separator ||= I18n.default_separator
|
23
26
|
|
24
27
|
if separator != FLATTEN_SEPARATOR
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
from_str = "#{FLATTEN_SEPARATOR}#{separator}"
|
29
|
+
to_str = "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}"
|
30
|
+
|
31
|
+
keys.map! { |k| k.to_s.tr from_str, to_str }
|
29
32
|
end
|
30
33
|
|
31
34
|
keys.join(".")
|
data/lib/i18n/core_ext/hash.rb
CHANGED
@@ -18,12 +18,24 @@ module I18n
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
# deep_merge from activesupport 5
|
22
|
+
# Copyright (c) 2005-2019 David Heinemeier Hansson
|
23
|
+
def deep_merge(other_hash, &block)
|
24
|
+
dup.deep_merge!(other_hash, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# deep_merge! from activesupport 5
|
28
|
+
# Copyright (c) 2005-2019 David Heinemeier Hansson
|
29
|
+
def deep_merge!(other_hash, &block)
|
30
|
+
merge!(other_hash) do |key, this_val, other_val|
|
31
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
32
|
+
this_val.deep_merge(other_val, &block)
|
33
|
+
elsif block_given?
|
34
|
+
block.call(key, this_val, other_val)
|
35
|
+
else
|
36
|
+
other_val
|
37
|
+
end
|
25
38
|
end
|
26
|
-
merge!(data, &merger)
|
27
39
|
end
|
28
40
|
|
29
41
|
def symbolize_key(key)
|
@@ -60,7 +60,7 @@ module I18n
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def defaults=(defaults)
|
63
|
-
@defaults = defaults.
|
63
|
+
@defaults = defaults.flat_map { |default| compute(default, false) }
|
64
64
|
end
|
65
65
|
attr_reader :defaults
|
66
66
|
|
@@ -84,13 +84,15 @@ module I18n
|
|
84
84
|
protected
|
85
85
|
|
86
86
|
def compute(tags, include_defaults = true, exclude = [])
|
87
|
-
result = Array(tags).
|
87
|
+
result = Array(tags).flat_map do |tag|
|
88
88
|
tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude
|
89
89
|
tags.each { |_tag| tags += compute(@map[_tag], false, exclude + tags) if @map[_tag] }
|
90
90
|
tags
|
91
|
-
end
|
91
|
+
end
|
92
92
|
result.push(*defaults) if include_defaults
|
93
|
-
result.uniq
|
93
|
+
result.uniq!
|
94
|
+
result.compact!
|
95
|
+
result
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
@@ -3,18 +3,20 @@ module I18n
|
|
3
3
|
module Tag
|
4
4
|
module Parents
|
5
5
|
def parent
|
6
|
-
@parent ||=
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
@parent ||=
|
7
|
+
begin
|
8
|
+
segs = to_a
|
9
|
+
segs.compact!
|
10
|
+
segs.length > 1 ? self.class.tag(*segs[0..(segs.length - 2)].join('-')) : nil
|
11
|
+
end
|
10
12
|
end
|
11
13
|
|
12
14
|
def self_and_parents
|
13
|
-
@self_and_parents ||= [self]
|
15
|
+
@self_and_parents ||= [self].concat parents
|
14
16
|
end
|
15
17
|
|
16
18
|
def parents
|
17
|
-
@parents ||=
|
19
|
+
@parents ||= parent ? [parent].concat(parent.parents) : []
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -52,19 +52,20 @@ module I18n
|
|
52
52
|
test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do
|
53
53
|
setup_time_proc_translations
|
54
54
|
time = ::Time.utc(2008, 3, 1, 6, 0)
|
55
|
-
assert_equal I18n::Tests::Localization::Procs.inspect_args([time, {}
|
55
|
+
assert_equal I18n::Tests::Localization::Procs.inspect_args([time], {}), I18n.l(time, :format => :proc, :locale => :ru)
|
56
56
|
end
|
57
57
|
|
58
58
|
test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
59
59
|
setup_time_proc_translations
|
60
60
|
time = ::Time.utc(2008, 3, 1, 6, 0)
|
61
61
|
options = { :foo => 'foo' }
|
62
|
-
assert_equal I18n::Tests::Localization::Procs.inspect_args([time, options
|
62
|
+
assert_equal I18n::Tests::Localization::Procs.inspect_args([time], options), I18n.l(time, **options.merge(:format => :proc, :locale => :ru))
|
63
63
|
end
|
64
64
|
|
65
65
|
protected
|
66
66
|
|
67
|
-
def self.inspect_args(args)
|
67
|
+
def self.inspect_args(args, kwargs)
|
68
|
+
args << kwargs
|
68
69
|
args = args.map do |arg|
|
69
70
|
case arg
|
70
71
|
when ::Time, ::DateTime
|
@@ -85,12 +86,12 @@ module I18n
|
|
85
86
|
I18n.backend.store_translations :ru, {
|
86
87
|
:time => {
|
87
88
|
:formats => {
|
88
|
-
:proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
|
89
|
+
:proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) }
|
89
90
|
}
|
90
91
|
},
|
91
92
|
:date => {
|
92
93
|
:formats => {
|
93
|
-
:proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
|
94
|
+
:proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) }
|
94
95
|
},
|
95
96
|
:'day_names' => lambda { |key, options|
|
96
97
|
(options[:format] =~ /^%A/) ?
|
data/lib/i18n/tests/procs.rb
CHANGED
@@ -8,6 +8,11 @@ module I18n
|
|
8
8
|
assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo')
|
9
9
|
end
|
10
10
|
|
11
|
+
test "lookup: given a translation is a proc it passes the interpolation values as keyword arguments" do
|
12
|
+
I18n.backend.store_translations(:en, :a_lambda => lambda { |key, foo:, **| I18n::Tests::Procs.filter_args(key, foo: foo) })
|
13
|
+
assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo')
|
14
|
+
end
|
15
|
+
|
11
16
|
test "defaults: given a default is a Proc it calls it with the key and interpolation values" do
|
12
17
|
proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
13
18
|
assert_equal '[nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo')
|
data/lib/i18n/version.rb
CHANGED
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.8.
|
4
|
+
version: 1.8.3
|
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: 2020-
|
16
|
+
date: 2020-06-05 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: concurrent-ruby
|
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
121
|
- !ruby/object:Gem::Version
|
122
122
|
version: 1.3.5
|
123
123
|
requirements: []
|
124
|
-
rubygems_version: 3.
|
124
|
+
rubygems_version: 3.1.2
|
125
125
|
signing_key:
|
126
126
|
specification_version: 4
|
127
127
|
summary: New wave Internationalization support for Ruby
|