i18n 1.7.1 → 1.8.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2d329752d461ff5287721f9bd5fee7f33a102562eaee86e6a9ab2cb2fbdae44
4
- data.tar.gz: 305fc47d8004f06f2589d1bccb015c772e1122c18e4328956a89833e473f6e29
3
+ metadata.gz: 37cc527d32916bffa8e32840086ef15b9f30c8eb08cb8f65bb6a4faf5d00a66e
4
+ data.tar.gz: f3f6a1a5724fe61ee5e9111bc167708d248fe7e3d700c10c0485fbd4bdf7b17e
5
5
  SHA512:
6
- metadata.gz: 16bc9ad463daaea66200aac4eade44ab199cdd4cf29e0a2d0eb0de3230ceee005d67aaa03459e2f364d1638d2cc6e9f3f8b378f7f0b6cff685f88e66044d9f1a
7
- data.tar.gz: 157350c5f080cb7fc1ba074411c06d364332d66e2e23f512f1a263fcf9e23ff309f2e696da582862effd9d22a9207c8f6191fbaf5806c3f94ab1b212e5630c00
6
+ metadata.gz: 638f732a18f9b9a26a4085320b24a56e3205944cdd1db8d6e751ca106ec848e88224e212fc83ce6324c61d34c471b66d67e3319620f16ae7d4b9ce43d053124e
7
+ data.tar.gz: ba6baab0a49d1e18b7fff46c0bf8c1f8d23bb74d68cca6ae33b7ddf6484de02ae9de24d7d2ee9cb3e77d2acd67e5b69df7e1e7ae19fc7bb265dd47707354f763
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 Internationalization and localization solution.
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](http://guides.rubyonrails.org/i18n.html) for an example of its usage.
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
- * translation and localization
55
- * interpolation of values to translations (Ruby 1.9 compatible syntax)
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
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/svenfuchs/i18n/wiki
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
- https://github.com/svenfuchs/i18n/graphs/contributors
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
 
@@ -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.map { |k| normalize_key(k, separator) }.flatten
392
+ key.flat_map { |k| normalize_key(k, separator) }
393
393
  else
394
394
  keys = key.to_s.split(separator)
395
395
  keys.delete('')
@@ -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)
@@ -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?(I18n::Locale::Fallbacks) ? fallbacks : I18n::Locale::Fallbacks.new(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
- return result unless result.nil?
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
@@ -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].flatten.compact
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
- keys.map! do |k|
26
- k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}",
27
- "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}")
28
- end
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(".")
@@ -29,7 +29,7 @@ module I18n
29
29
  # either pick a special :zero translation even for languages where the
30
30
  # pluralizer does not return a :zero key.
31
31
  def pluralize(locale, entry, count)
32
- return entry unless entry.is_a?(Hash) && count && entry.values.none? { |v| v.is_a?(Hash) }
32
+ return entry unless entry.is_a?(Hash) && count
33
33
 
34
34
  pluralizer = pluralizer(locale)
35
35
  if pluralizer.respond_to?(:call)
@@ -18,12 +18,24 @@ module I18n
18
18
  end
19
19
  end
20
20
 
21
- # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
22
- def deep_merge!(data)
23
- merger = lambda do |_key, v1, v2|
24
- Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
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 if method_defined? :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", :"de-DE", :de, :"en-US", :en]
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.map { |default| compute(default, false) }.flatten
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).collect do |tag|
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.flatten
91
+ end
92
92
  result.push(*defaults) if include_defaults
93
- result.uniq.compact
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 ||= begin
7
- segs = to_a.compact
8
- segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil
9
- end
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] + parents
15
+ @self_and_parents ||= [self].concat parents
14
16
  end
15
17
 
16
18
  def parents
17
- @parents ||= ([parent] + (parent ? parent.parents : [])).compact
19
+ @parents ||= parent ? [parent].concat(parent.parents) : []
18
20
  end
19
21
  end
20
22
  end
@@ -19,7 +19,7 @@ module I18n
19
19
  end
20
20
 
21
21
  def subtags
22
- @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
22
+ @subtags = tag.to_s.split('-').map!(&:to_s)
23
23
  end
24
24
 
25
25
  def to_sym
@@ -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, {}]), I18n.l(time, :format => :proc, :locale => :ru)
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]), I18n.l(time, **options.merge(:format => :proc, :locale => :ru))
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/) ?
@@ -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')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18n
4
- VERSION = "1.7.1"
4
+ VERSION = "1.8.4"
5
5
  end
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.7.1
4
+ version: 1.8.4
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: 2020-01-07 00:00:00.000000000 Z
16
+ date: 2020-07-20 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby
@@ -95,11 +95,15 @@ post_install_message: |2+
95
95
  HEADS UP! i18n 1.1 changed fallbacks to exclude default locale.
96
96
  But that may break your application.
97
97
 
98
+ If you are upgrading your Rails application from an older version of Rails:
99
+
98
100
  Please check your Rails app for 'config.i18n.fallbacks = true'.
99
101
  If you're using I18n (>= 1.1.0) and Rails (< 5.2.2), this should be
100
102
  'config.i18n.fallbacks = [I18n.default_locale]'.
101
103
  If not, fallbacks will be broken in your app by I18n 1.1.x.
102
104
 
105
+ If you are starting a NEW Rails application, you can ignore this notice.
106
+
103
107
  For more info see:
104
108
  https://github.com/svenfuchs/i18n/releases/tag/v1.1.0
105
109
 
@@ -118,7 +122,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
122
  version: 1.3.5
119
123
  requirements: []
120
124
  rubygems_version: 3.1.2
121
- signing_key:
125
+ signing_key:
122
126
  specification_version: 4
123
127
  summary: New wave Internationalization support for Ruby
124
128
  test_files: []
129
+ ...