r18n-core 4.0.0 → 5.0.1
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/ChangeLog.md +398 -0
- data/README.md +23 -13
- data/lib/r18n-core.rb +10 -25
- data/lib/r18n-core/filter_list.rb +6 -3
- data/lib/r18n-core/filters.rb +21 -22
- data/lib/r18n-core/i18n.rb +9 -16
- data/lib/r18n-core/locale.rb +20 -21
- data/lib/r18n-core/locales/cy.rb +1 -1
- data/lib/r18n-core/locales/en-au.rb +1 -1
- data/lib/r18n-core/locales/en-gb.rb +1 -1
- data/lib/r18n-core/locales/en-us.rb +1 -1
- data/lib/r18n-core/locales/en.rb +2 -2
- data/lib/r18n-core/locales/es-cl.rb +1 -1
- data/lib/r18n-core/locales/es-us.rb +1 -1
- data/lib/r18n-core/locales/es.rb +2 -0
- data/lib/r18n-core/locales/fi.rb +2 -2
- data/lib/r18n-core/locales/fr.rb +3 -3
- data/lib/r18n-core/locales/it.rb +3 -3
- data/lib/r18n-core/locales/pt.rb +2 -0
- data/lib/r18n-core/locales/zh-cn.rb +1 -1
- data/lib/r18n-core/locales/zh-tw.rb +1 -1
- data/lib/r18n-core/locales/zh.rb +2 -0
- data/lib/r18n-core/translated.rb +4 -4
- data/lib/r18n-core/translated_string.rb +1 -6
- data/lib/r18n-core/translation.rb +1 -1
- data/lib/r18n-core/unsupported_locale.rb +2 -0
- data/lib/r18n-core/utils.rb +1 -1
- data/lib/r18n-core/version.rb +1 -1
- metadata +198 -89
- data/.rspec +0 -1
- data/Rakefile +0 -13
- data/r18n-core.gemspec +0 -29
- data/spec/filters_spec.rb +0 -327
- data/spec/i18n_spec.rb +0 -274
- data/spec/locale_spec.rb +0 -251
- data/spec/locales/af_spec.rb +0 -9
- data/spec/locales/cs_spec.rb +0 -23
- data/spec/locales/en-us_spec.rb +0 -28
- data/spec/locales/en_spec.rb +0 -13
- data/spec/locales/es-us_spec.rb +0 -11
- data/spec/locales/fa_spec.rb +0 -10
- data/spec/locales/fi_spec.rb +0 -9
- data/spec/locales/fr_spec.rb +0 -9
- data/spec/locales/hu_spec.rb +0 -19
- data/spec/locales/id_spec.rb +0 -23
- data/spec/locales/it_spec.rb +0 -10
- data/spec/locales/no_spec.rb +0 -9
- data/spec/locales/pl_spec.rb +0 -23
- data/spec/locales/ru_spec.rb +0 -23
- data/spec/locales/sk_spec.rb +0 -23
- data/spec/locales/th_spec.rb +0 -9
- data/spec/locales/vi_spec.rb +0 -9
- data/spec/r18n_spec.rb +0 -192
- data/spec/spec_helper.rb +0 -38
- data/spec/translated_spec.rb +0 -225
- data/spec/translation_spec.rb +0 -189
- data/spec/translations/extension/deep/en.yml +0 -1
- data/spec/translations/extension/en.yml +0 -2
- data/spec/translations/extension/notransl.yml +0 -1
- data/spec/translations/general/en.yml +0 -52
- data/spec/translations/general/nolocale.yml +0 -6
- data/spec/translations/general/ru.yml +0 -7
- data/spec/translations/two/en.yml +0 -2
- data/spec/translations/two/fr.yml +0 -0
- data/spec/translations/with_regions/en-US.yml +0 -0
- data/spec/translations/yaml/en-GB.yml +0 -1
- data/spec/translations/yaml/en-us.yml +0 -1
- data/spec/translations/yaml/en.yaml +0 -1
- data/spec/yaml_loader_spec.rb +0 -63
data/lib/r18n-core.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Main file to load all
|
3
|
+
# Main file to load all necessary classes for i18n support.
|
4
4
|
#
|
5
5
|
# Copyright (C) 2008 Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
6
6
|
#
|
@@ -35,40 +35,25 @@
|
|
35
35
|
require_relative File.join('r18n-core', file)
|
36
36
|
end
|
37
37
|
|
38
|
+
# Root module with singleton methods
|
38
39
|
module R18n
|
39
40
|
autoload :Translated, 'r18n-core/translated'
|
40
41
|
|
41
42
|
class << self
|
42
43
|
# Set I18n object globally. You can miss translation `places`, it will be
|
43
44
|
# taken from `R18n.default_places`.
|
44
|
-
def set(i18n
|
45
|
-
@i18n =
|
46
|
-
if block_given?
|
47
|
-
@setter = block
|
48
|
-
nil
|
49
|
-
elsif i18n.is_a? I18n
|
50
|
-
i18n
|
51
|
-
else
|
52
|
-
I18n.new(i18n, places)
|
53
|
-
end
|
45
|
+
def set(i18n, places = R18n.default_places)
|
46
|
+
@i18n = i18n.is_a?(I18n) ? i18n : I18n.new(i18n, places)
|
54
47
|
end
|
55
48
|
|
56
49
|
# Set I18n object to current thread.
|
57
|
-
def thread_set(i18n
|
58
|
-
|
59
|
-
thread[:r18n_setter] = block
|
60
|
-
thread[:r18n_i18n] = nil
|
61
|
-
else
|
62
|
-
thread[:r18n_i18n] = i18n
|
63
|
-
end
|
50
|
+
def thread_set(i18n)
|
51
|
+
thread[:r18n_i18n] = i18n
|
64
52
|
end
|
65
53
|
|
66
54
|
# Get I18n object for current thread.
|
67
55
|
def get
|
68
|
-
thread[:r18n_i18n] ||
|
69
|
-
(thread[:r18n_setter] && thread_set(thread[:r18n_setter].call)) ||
|
70
|
-
@i18n ||
|
71
|
-
(@setter && set(@setter.call))
|
56
|
+
thread[:r18n_i18n] || @i18n
|
72
57
|
end
|
73
58
|
|
74
59
|
# Clean translations cache.
|
@@ -145,7 +130,7 @@ module R18n
|
|
145
130
|
attr_writer :default_places
|
146
131
|
|
147
132
|
def default_places(&block)
|
148
|
-
if
|
133
|
+
if block
|
149
134
|
@default_places = block
|
150
135
|
elsif @default_places.is_a? Proc
|
151
136
|
@default_places.call
|
@@ -154,12 +139,12 @@ module R18n
|
|
154
139
|
end
|
155
140
|
end
|
156
141
|
|
157
|
-
# Default loader class, which will be used if you
|
142
|
+
# Default loader class, which will be used if you did not send loader to
|
158
143
|
# `I18n.new` (object with `available` and `load` methods).
|
159
144
|
attr_accessor :default_loader
|
160
145
|
|
161
146
|
# Loaders with extension translations. If application translations with
|
162
|
-
# same locale isn't exists, extension file
|
147
|
+
# same locale isn't exists, extension file will not be used.
|
163
148
|
attr_accessor :extension_places
|
164
149
|
|
165
150
|
# `Hash` of hash-like (see Moneta) object to store loaded translations.
|
@@ -57,7 +57,7 @@ module R18n
|
|
57
57
|
value = f.call(value, config, *params)
|
58
58
|
end
|
59
59
|
|
60
|
-
if value.
|
60
|
+
if value.instance_of? String
|
61
61
|
TranslatedString.new(value, config[:locale], config[:path], self)
|
62
62
|
else
|
63
63
|
value
|
@@ -66,9 +66,10 @@ module R18n
|
|
66
66
|
|
67
67
|
# `Array` of enabled filters with `filters_type` for `type`.
|
68
68
|
def enabled(filters_type, type)
|
69
|
-
|
69
|
+
case filters_type
|
70
|
+
when :passive
|
70
71
|
passive(type)
|
71
|
-
|
72
|
+
when :active
|
72
73
|
active(type)
|
73
74
|
else
|
74
75
|
all(type)
|
@@ -111,6 +112,8 @@ module R18n
|
|
111
112
|
# Filter list for I18n object with custom disabled/enabled filters.
|
112
113
|
class CustomFilterList < FilterList
|
113
114
|
def initialize(on, off)
|
115
|
+
super()
|
116
|
+
|
114
117
|
@on = Array(on).map { |i| Filters.defined[i] }
|
115
118
|
@off = Array(off).map { |i| Filters.defined[i] }
|
116
119
|
@changed_types = (@on + @off).map(&:types).flatten.uniq
|
data/lib/r18n-core/filters.rb
CHANGED
@@ -210,7 +210,7 @@ module R18n
|
|
210
210
|
|
211
211
|
Filter = Struct.new(:name, :types, :block, :enabled, :passive) do
|
212
212
|
def call(*params)
|
213
|
-
|
213
|
+
instance_exec(*params, &block)
|
214
214
|
end
|
215
215
|
|
216
216
|
def enabled?
|
@@ -224,7 +224,7 @@ module R18n
|
|
224
224
|
end
|
225
225
|
|
226
226
|
# Class to mark unpluralized translation.
|
227
|
-
class
|
227
|
+
class UnpluralizedTranslation < Translation
|
228
228
|
end
|
229
229
|
|
230
230
|
Filters.add('pl', :pluralization) do |content, config, param|
|
@@ -234,7 +234,7 @@ module R18n
|
|
234
234
|
type = 'n' unless content.key? type
|
235
235
|
content[type]
|
236
236
|
else
|
237
|
-
|
237
|
+
UnpluralizedTranslation.new(
|
238
238
|
config[:locale], config[:path],
|
239
239
|
locale: config[:locale], translations: content
|
240
240
|
)
|
@@ -243,13 +243,11 @@ module R18n
|
|
243
243
|
|
244
244
|
Filters.add(String, :variables) do |content, config, *params|
|
245
245
|
cached_params = []
|
246
|
-
content.to_s.gsub(
|
246
|
+
content.to_s.gsub(/%\d/) do |key|
|
247
247
|
i = key[1..-1].to_i
|
248
248
|
unless cached_params.include? i - 1
|
249
249
|
param = config[:locale].localize(params[i - 1])
|
250
|
-
if defined? ActiveSupport::SafeBuffer
|
251
|
-
param = ActiveSupport::SafeBuffer.new + param
|
252
|
-
end
|
250
|
+
param = ActiveSupport::SafeBuffer.new + param if defined? ActiveSupport::SafeBuffer
|
253
251
|
|
254
252
|
cached_params[i - 1] = param
|
255
253
|
end
|
@@ -260,13 +258,11 @@ module R18n
|
|
260
258
|
Filters.add(String, :named_variables) do |content, config, params|
|
261
259
|
if params.is_a? Hash
|
262
260
|
content = content.clone
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
content.gsub! "%{#{name}}", value
|
269
|
-
content.gsub! "{{#{name}}}", value
|
261
|
+
content.gsub!(/(?:%{(\w+)}|{{(\w+)}})/) do |name|
|
262
|
+
key = name.delete('%{}').to_sym
|
263
|
+
value = config[:locale].localize(params[key])
|
264
|
+
value = ActiveSupport::SafeBuffer.new + value if defined? ActiveSupport::SafeBuffer
|
265
|
+
value
|
270
266
|
end
|
271
267
|
end
|
272
268
|
content
|
@@ -277,20 +273,23 @@ module R18n
|
|
277
273
|
"#{translated}[#{untranslated}]"
|
278
274
|
end
|
279
275
|
|
280
|
-
Filters.add(Untranslated, :untranslated_bash) do |_v, _c,
|
281
|
-
"#{
|
276
|
+
Filters.add(Untranslated, :untranslated_bash) do |_v, _c, translated, untranslated|
|
277
|
+
"#{translated}\e[0;31m[#{untranslated}]\e[0m"
|
282
278
|
end
|
283
279
|
Filters.off(:untranslated_bash)
|
284
280
|
|
285
|
-
Filters.add(Untranslated, :untranslated_html) do |_v, _c,
|
281
|
+
Filters.add(Untranslated, :untranslated_html) do |_v, _c, translated, untranslated|
|
286
282
|
prefix = '<span style="color: red">['
|
287
283
|
postfix = ']</span>'
|
288
|
-
if
|
289
|
-
|
290
|
-
|
291
|
-
|
284
|
+
if defined? ActiveSupport::SafeBuffer
|
285
|
+
## Not every project with `ActiveSupport` has `ActionView`
|
286
|
+
## https://github.com/r18n/r18n/issues/251
|
287
|
+
## I guess, we can trust to developers here
|
288
|
+
translated = ActiveSupport::SafeBuffer.new + translated
|
289
|
+
untranslated = ActiveSupport::SafeBuffer.new + untranslated
|
290
|
+
translated + prefix.html_safe + untranslated + postfix.html_safe
|
292
291
|
else
|
293
|
-
Utils.escape_html(
|
292
|
+
Utils.escape_html(translated) + prefix + Utils.escape_html(untranslated) + postfix
|
294
293
|
end
|
295
294
|
end
|
296
295
|
Filters.off(:untranslated_html)
|
data/lib/r18n-core/i18n.rb
CHANGED
@@ -137,15 +137,11 @@ module R18n
|
|
137
137
|
def initialize(locales, translation_places = nil, opts = {})
|
138
138
|
locales = Array(locales)
|
139
139
|
|
140
|
-
if !locales.empty? && Locale.exists?(locales.first)
|
141
|
-
locales += Locale.load(locales.first).sublocales
|
142
|
-
end
|
143
|
-
locales << self.class.default
|
144
140
|
locales.each_with_index do |locale, i|
|
145
|
-
|
146
|
-
|
147
|
-
end
|
141
|
+
locales.insert(i + 1, locale.match(/([^_-]+)[_-]/)[1]) if locale.match?(/[^_-]+[_-]/)
|
142
|
+
locales.insert(i + 1, *(Locale.load(locale).sublocales - locales)) if Locale.exists?(locale)
|
148
143
|
end
|
144
|
+
locales << self.class.default
|
149
145
|
locales.map! { |i| i.to_s.downcase }.uniq!
|
150
146
|
@locales_codes = locales
|
151
147
|
@locales = locales.each_with_object([]) do |locale, result|
|
@@ -189,10 +185,8 @@ module R18n
|
|
189
185
|
@available_codes ||= @translation_places
|
190
186
|
.inject([]) { |all, i| all + i.available }
|
191
187
|
.uniq.map { |i| i.code.downcase }
|
192
|
-
(@locales_codes & @available_codes).join(',')
|
193
|
-
@filters.hash.
|
194
|
-
R18n.default_loader.hash.to_s + '_' +
|
195
|
-
@translation_places.hash.to_s + '_' +
|
188
|
+
"#{(@locales_codes & @available_codes).join(',')}@" \
|
189
|
+
"#{@filters.hash}_#{R18n.default_loader.hash}_#{@translation_places.hash}_" +
|
196
190
|
R18n.extension_places.hash.to_s
|
197
191
|
end
|
198
192
|
|
@@ -240,9 +234,8 @@ module R18n
|
|
240
234
|
next unless loaded
|
241
235
|
|
242
236
|
available_in_extensions.each do |extension, available|
|
243
|
-
if available.include? locale
|
244
|
-
|
245
|
-
end
|
237
|
+
@translation.merge! extension.load(locale), locale if available.include? locale
|
238
|
+
|
246
239
|
if available.include? locale.parent
|
247
240
|
@translation.merge! extension.load(locale.parent), locale.parent
|
248
241
|
end
|
@@ -270,8 +263,8 @@ module R18n
|
|
270
263
|
# i18n.l Time.now.to_date #=> "07/01/09"
|
271
264
|
# i18n.l Time.now, :human #=> "now"
|
272
265
|
# i18n.l Time.now, :full #=> "Jule 1st, 2009 12:59"
|
273
|
-
def localize(object, format = nil,
|
274
|
-
locale.localize(object, format, self,
|
266
|
+
def localize(object, format = nil, **kwargs)
|
267
|
+
locale.localize(object, format, i18n: self, **kwargs)
|
275
268
|
end
|
276
269
|
alias l localize
|
277
270
|
|
data/lib/r18n-core/locale.rb
CHANGED
@@ -109,6 +109,7 @@ module R18n
|
|
109
109
|
# locale.code #=> "en"
|
110
110
|
def set(properties)
|
111
111
|
properties.each_pair do |key, value|
|
112
|
+
undef_method key if method_defined? key
|
112
113
|
define_method(key) { value }
|
113
114
|
end
|
114
115
|
end
|
@@ -127,7 +128,7 @@ module R18n
|
|
127
128
|
@parent = self.class.superclass.new
|
128
129
|
end
|
129
130
|
|
130
|
-
set sublocales:
|
131
|
+
set sublocales: [],
|
131
132
|
week_start: :monday,
|
132
133
|
time_am: 'AM',
|
133
134
|
time_pm: 'PM',
|
@@ -175,7 +176,7 @@ module R18n
|
|
175
176
|
# `:full` ("01 Jule, 2009"), `:human` ("yesterday"),
|
176
177
|
# `:standard` ("07/01/09") or `:month` for standalone month
|
177
178
|
# name. Default format is `:standard`.
|
178
|
-
def localize(obj, format = nil, *
|
179
|
+
def localize(obj, format = nil, *args, **kwargs)
|
179
180
|
case obj
|
180
181
|
when Integer
|
181
182
|
format_integer(obj)
|
@@ -184,7 +185,7 @@ module R18n
|
|
184
185
|
when Time, DateTime, Date
|
185
186
|
return strftime(obj, format) if format.is_a? String
|
186
187
|
return month_standalone[obj.month - 1] if format == :month
|
187
|
-
return obj.to_s if format == :human && !
|
188
|
+
return obj.to_s if format == :human && !kwargs.key?(:i18n)
|
188
189
|
|
189
190
|
type = obj.is_a?(Date) && !obj.is_a?(DateTime) ? 'date' : 'time'
|
190
191
|
format ||= :standard
|
@@ -194,14 +195,14 @@ module R18n
|
|
194
195
|
raise ArgumentError, "Unknown time formatter #{format}"
|
195
196
|
end
|
196
197
|
|
197
|
-
send format_method_name, obj, *
|
198
|
+
send format_method_name, obj, *args, **kwargs
|
198
199
|
else
|
199
200
|
format_method_name =
|
200
|
-
"format_#{Utils.underscore(obj.class.name)}_#{format}"
|
201
|
+
"format_#{Utils.underscore(obj.class.name).tr('/', '_')}_#{format}"
|
201
202
|
|
202
203
|
return obj.to_s unless respond_to? format_method_name
|
203
204
|
|
204
|
-
send format_method_name, obj, *
|
205
|
+
send format_method_name, obj, *args, **kwargs
|
205
206
|
end
|
206
207
|
end
|
207
208
|
|
@@ -250,7 +251,7 @@ module R18n
|
|
250
251
|
end
|
251
252
|
|
252
253
|
# Format `time` and set `date`
|
253
|
-
def format_time(date, time, with_seconds: false)
|
254
|
+
def format_time(date, time, with_seconds: false, **_kwargs)
|
254
255
|
strftime(
|
255
256
|
time, with_seconds ? time_with_seconds_format : time_format
|
256
257
|
).sub('_', date.to_s)
|
@@ -259,12 +260,12 @@ module R18n
|
|
259
260
|
# Format `time` in human usable form. For example "5 minutes ago" or
|
260
261
|
# "yesterday". In `now` you can set base time, which be used to get relative
|
261
262
|
# time. For special cases you can replace it in locale's class.
|
262
|
-
def format_time_human(time, i18n
|
263
|
+
def format_time_human(time, i18n:, now: time.class.now, **_kwargs)
|
263
264
|
diff = time - now
|
264
265
|
minutes = time.is_a?(DateTime) ? diff * 24 * 60.0 : diff / 60.0
|
265
266
|
diff = minutes.abs
|
266
267
|
if (diff > 24 * 60) || (time.mday != now.mday && diff > 12 * 24)
|
267
|
-
format_time(format_date_human(time.to_date,
|
268
|
+
format_time(format_date_human(time.to_date, now: now.to_date, i18n: i18n), time)
|
268
269
|
elsif minutes > -1 && minutes < 1
|
269
270
|
i18n.human_time.now
|
270
271
|
elsif minutes >= 60
|
@@ -279,22 +280,20 @@ module R18n
|
|
279
280
|
end
|
280
281
|
|
281
282
|
# Format `time` in compact form. For example, "12/31/09 12:59".
|
282
|
-
def format_time_standard(time, *
|
283
|
-
|
284
|
-
format_time(format_date_standard(time), time, **options)
|
283
|
+
def format_time_standard(time, *args, **kwargs)
|
284
|
+
format_time(format_date_standard(time), time, *args, **kwargs)
|
285
285
|
end
|
286
286
|
|
287
287
|
# Format `time` in most official form. For example, "December 31st, 2009
|
288
288
|
# 12:59". For special cases you can replace it in locale's class.
|
289
|
-
def format_time_full(time,
|
290
|
-
|
291
|
-
format_time(format_date_full(time), time, **options)
|
289
|
+
def format_time_full(time, **kwargs)
|
290
|
+
format_time(format_date_full(time, **kwargs), time, **kwargs)
|
292
291
|
end
|
293
292
|
|
294
|
-
# Format `date` in human usable form. For example "5 days ago" or
|
295
|
-
#
|
296
|
-
#
|
297
|
-
def format_date_human(date,
|
293
|
+
# Format `date` in human usable form. For example "5 days ago" or "yesterday".
|
294
|
+
# In `:now` you can set base time, which be used to get relative time.
|
295
|
+
# For special cases you can replace it in locale's class.
|
296
|
+
def format_date_human(date, *_args, i18n:, now: Date.today, **_kwargs)
|
298
297
|
days = (date - now).to_i
|
299
298
|
case days
|
300
299
|
when -6..-2
|
@@ -308,7 +307,7 @@ module R18n
|
|
308
307
|
when 2..6
|
309
308
|
i18n.human_time.after_days(days)
|
310
309
|
else
|
311
|
-
format_date_full(date, date.year != now.year)
|
310
|
+
format_date_full(date, year: date.year != now.year)
|
312
311
|
end
|
313
312
|
end
|
314
313
|
|
@@ -320,7 +319,7 @@ module R18n
|
|
320
319
|
# Format `date` in most official form. For example, "December 31st, 2009".
|
321
320
|
# For special cases you can replace it in locale's class. If `year` is false
|
322
321
|
# date will be without year.
|
323
|
-
def format_date_full(date, year
|
322
|
+
def format_date_full(date, year: true, **_kwargs)
|
324
323
|
format = full_format
|
325
324
|
format = year_format.sub('_', format) if year
|
326
325
|
strftime(date, format)
|
data/lib/r18n-core/locales/cy.rb
CHANGED
@@ -40,7 +40,7 @@ module R18n
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def format_date_full(date, year
|
43
|
+
def format_date_full(date, year: true, **_kwargs)
|
44
44
|
format = full_format
|
45
45
|
format = year_format.sub('_', format) if year
|
46
46
|
strftime(date, format.sub('%e', ordinalize(date.mday)))
|
data/lib/r18n-core/locales/en.rb
CHANGED
@@ -6,7 +6,7 @@ module R18n
|
|
6
6
|
class En < Locale
|
7
7
|
set(
|
8
8
|
title: 'English',
|
9
|
-
sublocales: [],
|
9
|
+
sublocales: %w[en-US en-GB en-AU],
|
10
10
|
|
11
11
|
week_start: :sunday,
|
12
12
|
wday_names: %w[
|
@@ -41,7 +41,7 @@ module R18n
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
def format_date_full(date, year
|
44
|
+
def format_date_full(date, year: true, **_kwargs)
|
45
45
|
format = full_format
|
46
46
|
format = year_format.sub('_', format) if year
|
47
47
|
strftime(date, format.sub('%-d', ordinalize(date.mday)))
|