i18n 1.8.2 → 1.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -22
- data/lib/i18n.rb +7 -7
- data/lib/i18n/backend/base.rb +3 -2
- data/lib/i18n/backend/chain.rb +3 -4
- data/lib/i18n/backend/fallbacks.rb +14 -3
- data/lib/i18n/backend/flatten.rb +8 -5
- data/lib/i18n/core_ext/hash.rb +17 -5
- data/lib/i18n/interpolate/ruby.rb +1 -1
- data/lib/i18n/locale/fallbacks.rb +7 -5
- 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 +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecfb802a53a50fa0b480295092adbe3064584ef69f06b81851b95bd15f49bca2
|
4
|
+
data.tar.gz: 84e6ce2a82b2ce6f52ba8358b5c409c7fe48ff790ca7f3680d922557b06c7f56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8cf31834170e4aea3f2b25cfad6930372f4ab5f781a9fb7c5f78e6ddabb5316f45a67c5258375d50b5b4ea7f7a97d3a44eda6c34d1a8e7b8c5e5a5f21a95042
|
7
|
+
data.tar.gz: 49532d4362b42b2dcf5f8ef60afd677e64d23aece076933623f0e102f3a803383bff1f6c9add7d00097044459cbd609dd71ead49a965af1636c7a3452f3a885b
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://github.com/ruby-i18n/i18n/workflows/Ruby/badge.svg)](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
@@ -192,7 +192,7 @@ module I18n
|
|
192
192
|
# I18n.t(:salutation, { :gender => 'w', :name => 'Smith' })
|
193
193
|
# I18n.t(:salutation, any_hash)
|
194
194
|
#
|
195
|
-
def translate(key = nil,
|
195
|
+
def translate(key = nil, throw: false, raise: false, locale: nil, **options) # TODO deprecate :raise
|
196
196
|
locale ||= config.locale
|
197
197
|
raise Disabled.new('t') if locale == false
|
198
198
|
enforce_available_locales!(locale)
|
@@ -217,17 +217,17 @@ module I18n
|
|
217
217
|
|
218
218
|
# Wrapper for <tt>translate</tt> that adds <tt>:raise => true</tt>. With
|
219
219
|
# this option, if no translation is found, it will raise <tt>I18n::MissingTranslationData</tt>
|
220
|
-
def translate!(key, options
|
221
|
-
translate(key, **options
|
220
|
+
def translate!(key, **options)
|
221
|
+
translate(key, **options, raise: true)
|
222
222
|
end
|
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
|
@@ -281,7 +281,7 @@ module I18n
|
|
281
281
|
# I18n.transliterate("Jürgen") # => "Juergen"
|
282
282
|
# I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
|
283
283
|
# I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
|
284
|
-
def transliterate(key,
|
284
|
+
def transliterate(key, throw: false, raise: false, locale: nil, replacement: nil, **options)
|
285
285
|
locale ||= config.locale
|
286
286
|
raise Disabled.new('transliterate') if locale == false
|
287
287
|
enforce_available_locales!(locale)
|
@@ -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
|
|
@@ -20,7 +20,7 @@ module I18n
|
|
20
20
|
|
21
21
|
# Sets the current fallbacks implementation. Use this to set a different fallbacks implementation.
|
22
22
|
def fallbacks=(fallbacks)
|
23
|
-
@@fallbacks = fallbacks
|
23
|
+
@@fallbacks = fallbacks.is_a?(Array) ? I18n::Locale::Fallbacks.new(fallbacks) : fallbacks
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -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)
|
@@ -8,7 +8,7 @@ module I18n
|
|
8
8
|
/%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
|
9
9
|
].freeze
|
10
10
|
INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
|
11
|
-
deprecate_constant :INTERPOLATION_PATTERN
|
11
|
+
deprecate_constant :INTERPOLATION_PATTERN
|
12
12
|
|
13
13
|
class << self
|
14
14
|
# Return String or raises MissingInterpolationArgument exception.
|
@@ -26,7 +26,7 @@
|
|
26
26
|
#
|
27
27
|
# I18n.default_locale = :"en-US"
|
28
28
|
# I18n.fallbacks = I18n::Locale::Fallbacks.new(:"de-AT" => :"de-DE")
|
29
|
-
# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :
|
29
|
+
# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"de-DE"]
|
30
30
|
#
|
31
31
|
# # using a custom locale as default fallback locale
|
32
32
|
#
|
@@ -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.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: 2021-01-04 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: concurrent-ruby
|
@@ -86,10 +86,10 @@ homepage: https://github.com/ruby-i18n/i18n
|
|
86
86
|
licenses:
|
87
87
|
- MIT
|
88
88
|
metadata:
|
89
|
-
bug_tracker_uri: https://github.com/
|
90
|
-
changelog_uri: https://github.com/
|
89
|
+
bug_tracker_uri: https://github.com/ruby-i18n/i18n/issues
|
90
|
+
changelog_uri: https://github.com/ruby-i18n/i18n/releases
|
91
91
|
documentation_uri: https://guides.rubyonrails.org/i18n.html
|
92
|
-
source_code_uri: https://github.com/
|
92
|
+
source_code_uri: https://github.com/ruby-i18n/i18n
|
93
93
|
post_install_message: |2+
|
94
94
|
|
95
95
|
HEADS UP! i18n 1.1 changed fallbacks to exclude default locale.
|
@@ -121,8 +121,9 @@ 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.
|
125
|
-
signing_key:
|
124
|
+
rubygems_version: 3.2.3
|
125
|
+
signing_key:
|
126
126
|
specification_version: 4
|
127
127
|
summary: New wave Internationalization support for Ruby
|
128
128
|
test_files: []
|
129
|
+
...
|