mini_i18n 0.4.0 → 0.5.0
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/mini_i18n/localization.rb +74 -0
- data/lib/mini_i18n/utils.rb +0 -4
- data/lib/mini_i18n/version.rb +1 -1
- data/lib/mini_i18n.rb +51 -28
- data/spec/fixtures/locales/localization.yml +20 -0
- data/spec/fixtures/locales/multiple.yml +3 -0
- data/spec/localization_spec.rb +49 -0
- data/spec/mini_i18n_spec.rb +1 -11
- data/spec/spec_helper.rb +10 -0
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e1535503921791b7c7660516aab9b224eda60883
|
|
4
|
+
data.tar.gz: 87d9b5f991ba9dca7da8310b2fc76d43b82a9100
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 58ba16e72dc2d6e2211999a89948490721f4ee23d7fc9781f913395bb2a44e80a21605ad0b8f7cb0c8be92d528ecf1fe0f46318a93935bfe23d67438904f2a3f
|
|
7
|
+
data.tar.gz: adf6f4cedaf7fc8b7c58179eb4e57a3b98a85cdc4269111b69411fcac45a0a9844d81cc4273ffff95e0b801cc035b9a6ea98fcb1e0a5c7862290636000b5d692
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'time'
|
|
2
|
+
|
|
3
|
+
module MiniI18n
|
|
4
|
+
module Localization
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
DELIMITER_REGEX = /\d(?=(\d{3})+(?!\d))/
|
|
8
|
+
DAYS_MONTHS_REGEX = /%[aAbB]/
|
|
9
|
+
|
|
10
|
+
def localize(object, options = {})
|
|
11
|
+
case object
|
|
12
|
+
when Numeric
|
|
13
|
+
localize_number(object, options)
|
|
14
|
+
when Date
|
|
15
|
+
localize_datetime(object, options.merge(type: :date))
|
|
16
|
+
when Time, DateTime
|
|
17
|
+
localize_datetime(object, options.merge(type: :time))
|
|
18
|
+
when String
|
|
19
|
+
localize_string(object, options)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
alias l localize
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def localize_number(number, options)
|
|
27
|
+
locale = options[:locale]
|
|
28
|
+
delimiter = MiniI18n.t("number.format.delimiter", locale: locale)
|
|
29
|
+
separator = MiniI18n.t("number.format.separator", locale: locale)
|
|
30
|
+
integer, fractional = number.to_s.split(separator)
|
|
31
|
+
|
|
32
|
+
integer.to_s.gsub!(DELIMITER_REGEX) do |match|
|
|
33
|
+
"#{match}#{delimiter}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
number = [integer, fractional].compact.join(separator)
|
|
37
|
+
|
|
38
|
+
if as = options[:as]
|
|
39
|
+
number = MiniI18n.t("number.as.#{as}", number: number, locale: locale)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
number
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def localize_datetime(object, options)
|
|
46
|
+
locale = options[:locale]
|
|
47
|
+
type = options[:type]
|
|
48
|
+
format = MiniI18n.t("#{type}.formats.#{options[:format] || 'default'}", locale: locale)
|
|
49
|
+
|
|
50
|
+
format.gsub!(DAYS_MONTHS_REGEX) do |match|
|
|
51
|
+
{
|
|
52
|
+
'%a' => MiniI18n.t('date.abbr_day_names', locale: locale)[object.wday],
|
|
53
|
+
'%A' => MiniI18n.t('date.day_names', locale: locale)[object.wday],
|
|
54
|
+
'%b' => MiniI18n.t('date.abbr_month_names', locale: locale)[object.month - 1],
|
|
55
|
+
'%B' => MiniI18n.t('date.month_names', locale: locale)[object.month - 1]
|
|
56
|
+
}[match]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
object.strftime(format)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def localize_string(string, options)
|
|
63
|
+
object = if options[:type] == :number || options[:as]
|
|
64
|
+
string.to_f
|
|
65
|
+
elsif options[:type] == :date
|
|
66
|
+
Date.parse(string) rescue nil
|
|
67
|
+
else
|
|
68
|
+
Time.parse(string) rescue nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
object && localize(object, options)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
data/lib/mini_i18n/utils.rb
CHANGED
data/lib/mini_i18n/version.rb
CHANGED
data/lib/mini_i18n.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
require "yaml"
|
|
2
2
|
require "mini_i18n/version"
|
|
3
3
|
require "mini_i18n/utils"
|
|
4
|
+
require "mini_i18n/localization"
|
|
4
5
|
|
|
5
6
|
module MiniI18n
|
|
6
7
|
class << self
|
|
8
|
+
include Localization
|
|
9
|
+
|
|
7
10
|
DEFAULT_LOCALE = :en
|
|
8
11
|
SEPARATOR = '.'
|
|
9
12
|
|
|
@@ -48,14 +51,7 @@ module MiniI18n
|
|
|
48
51
|
def load_translations(path)
|
|
49
52
|
Dir[path.to_s].each do |file|
|
|
50
53
|
YAML.load_file(file).each do |locale, new_translations|
|
|
51
|
-
locale
|
|
52
|
-
@@available_locales << locale unless available_locale?(locale)
|
|
53
|
-
|
|
54
|
-
if translations[locale]
|
|
55
|
-
translations[locale] = Utils.deep_merge(translations[locale], new_translations)
|
|
56
|
-
else
|
|
57
|
-
translations[locale] = new_translations
|
|
58
|
-
end
|
|
54
|
+
add_translations(locale.to_s, new_translations)
|
|
59
55
|
end
|
|
60
56
|
end
|
|
61
57
|
end
|
|
@@ -65,7 +61,6 @@ module MiniI18n
|
|
|
65
61
|
|
|
66
62
|
_locale = available_locale?(options[:locale]) || locale
|
|
67
63
|
scope = options[:scope]
|
|
68
|
-
count = options[:count]
|
|
69
64
|
|
|
70
65
|
keys = [_locale.to_s]
|
|
71
66
|
keys << scope.to_s.split(SEPARATOR) if scope
|
|
@@ -74,25 +69,9 @@ module MiniI18n
|
|
|
74
69
|
|
|
75
70
|
result = lookup(*keys)
|
|
76
71
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
if count && result.is_a?(Hash)
|
|
83
|
-
case count
|
|
84
|
-
when 0
|
|
85
|
-
result = result["zero"]
|
|
86
|
-
when 1
|
|
87
|
-
result = result["one"]
|
|
88
|
-
else
|
|
89
|
-
result = result["many"]
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
if result.respond_to?(:match) && result.match(/%{\w+}/)
|
|
94
|
-
result = Utils.interpolate(result, options)
|
|
95
|
-
end
|
|
72
|
+
result = with_fallbacks(result, keys)
|
|
73
|
+
result = with_pluralization(result, options)
|
|
74
|
+
result = with_interpolation(result, options)
|
|
96
75
|
|
|
97
76
|
result || options[:default]
|
|
98
77
|
end
|
|
@@ -116,5 +95,49 @@ module MiniI18n
|
|
|
116
95
|
def lookup(*keys)
|
|
117
96
|
translations.dig(*keys)
|
|
118
97
|
end
|
|
98
|
+
|
|
99
|
+
def add_translations(locale, new_translations)
|
|
100
|
+
@@available_locales << locale unless available_locale?(locale)
|
|
101
|
+
|
|
102
|
+
if translations[locale]
|
|
103
|
+
translations[locale] = Utils.deep_merge(translations[locale], new_translations)
|
|
104
|
+
else
|
|
105
|
+
translations[locale] = new_translations
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def with_fallbacks(result, keys)
|
|
110
|
+
if fallbacks && result.empty?
|
|
111
|
+
keys[0] = default_locale.to_s
|
|
112
|
+
result = lookup(*keys)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
result
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def with_pluralization(result, options)
|
|
119
|
+
count = options[:count]
|
|
120
|
+
|
|
121
|
+
if count && result.is_a?(Hash)
|
|
122
|
+
case count
|
|
123
|
+
when 0
|
|
124
|
+
result = result["zero"]
|
|
125
|
+
when 1
|
|
126
|
+
result = result["one"]
|
|
127
|
+
else
|
|
128
|
+
result = result["many"]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
result
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def with_interpolation(result, options)
|
|
136
|
+
if result.respond_to?(:match) && result.match(/%{\w+}/)
|
|
137
|
+
result = Utils.interpolate(result, options)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
result
|
|
141
|
+
end
|
|
119
142
|
end
|
|
120
143
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
en:
|
|
2
|
+
date:
|
|
3
|
+
formats:
|
|
4
|
+
default: "%A %d, %B, %Y"
|
|
5
|
+
short: "%d %b %y"
|
|
6
|
+
day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
|
|
7
|
+
abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
|
|
8
|
+
month_names: [January, February, March, April, May, June, July, August, September, October, November, December]
|
|
9
|
+
abbr_month_names: [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
|
|
10
|
+
time:
|
|
11
|
+
formats:
|
|
12
|
+
default: "%a %d, %B, %Y - %H:%M"
|
|
13
|
+
short: "%d %b %y - %H:%M"
|
|
14
|
+
number:
|
|
15
|
+
format:
|
|
16
|
+
delimiter: ','
|
|
17
|
+
separator: '.'
|
|
18
|
+
as:
|
|
19
|
+
currency: '%{number} $'
|
|
20
|
+
distance: 'Distance: %{number} miles'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
RSpec.describe MiniI18n::Localization do
|
|
2
|
+
let(:time) { Time.new(2018, 8, 7, 22, 30) }
|
|
3
|
+
|
|
4
|
+
describe 'date' do
|
|
5
|
+
it 'accepts different formats' do
|
|
6
|
+
date = time.to_date
|
|
7
|
+
expect(MiniI18n.l(date)).to eq 'Tuesday 07, August, 2018'
|
|
8
|
+
expect(MiniI18n.l(date, format: :short)).to eq '07 Aug 18'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe 'time' do
|
|
13
|
+
it 'accepts different formats' do
|
|
14
|
+
expect(MiniI18n.l(time)).to eq 'Tue 07, August, 2018 - 22:30'
|
|
15
|
+
expect(MiniI18n.l(time, format: :short)).to eq '07 Aug 18 - 22:30'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe 'string' do
|
|
20
|
+
it 'accepts and defaults to time' do
|
|
21
|
+
time_string = time.to_s
|
|
22
|
+
expect(MiniI18n.l(time_string)).to eq 'Tue 07, August, 2018 - 22:30'
|
|
23
|
+
expect(MiniI18n.l(time_string, type: :time)).to eq 'Tue 07, August, 2018 - 22:30'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'to date' do
|
|
27
|
+
date_string = time.to_date.to_s
|
|
28
|
+
expect(MiniI18n.l(date_string, type: :date, format: :short)).to eq '07 Aug 18'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'to number' do
|
|
32
|
+
expect(MiniI18n.l("1000000", type: :number)).to eq '1,000,000.0'
|
|
33
|
+
expect(MiniI18n.l("1000000", as: :currency)).to eq '1,000,000.0 $'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'number' do
|
|
38
|
+
it 'uses defined format' do
|
|
39
|
+
expect(MiniI18n.l(9000)).to eq '9,000'
|
|
40
|
+
expect(MiniI18n.l(9000.50)).to eq '9,000.5'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'as' do
|
|
44
|
+
expect(MiniI18n.l(9000, as: :currency)).to eq '9,000 $'
|
|
45
|
+
expect(MiniI18n.l(9000, as: :currency, locale: :es)).to eq '9000 €'
|
|
46
|
+
expect(MiniI18n.l(125.5, as: :distance)).to eq 'Distance: 125.5 miles'
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/spec/mini_i18n_spec.rb
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
RSpec.describe MiniI18n do
|
|
2
|
-
before(:all) do
|
|
3
|
-
MiniI18n.load_translations File.expand_path(__dir__ + '/fixtures/locales/*')
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
before(:each) do
|
|
7
|
-
MiniI18n.locale = :en
|
|
8
|
-
MiniI18n.fallbacks = false
|
|
9
|
-
MiniI18n.available_locales = [:en, :es, :fr]
|
|
10
|
-
end
|
|
11
|
-
|
|
12
2
|
describe 'load_translations' do
|
|
13
3
|
it "allows to load multiple locales and translations from different files" do
|
|
14
4
|
expect(MiniI18n.available_locales).to eq ["en", "es", "fr"]
|
|
@@ -89,7 +79,7 @@ RSpec.describe MiniI18n do
|
|
|
89
79
|
it "pluralization" do
|
|
90
80
|
expect(MiniI18n.t('notifications', count: 0)).to eq 'no unread notifications'
|
|
91
81
|
expect(MiniI18n.t('notifications', count: 1)).to eq '1 unread notification'
|
|
92
|
-
expect(MiniI18n.t('notifications', count:
|
|
82
|
+
expect(MiniI18n.t('notifications', count: 5)).to eq '5 unread notifications'
|
|
93
83
|
end
|
|
94
84
|
end
|
|
95
85
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,4 +3,14 @@ require "mini_i18n"
|
|
|
3
3
|
RSpec.configure do |config|
|
|
4
4
|
config.order = :rand
|
|
5
5
|
config.disable_monkey_patching!
|
|
6
|
+
|
|
7
|
+
config.before(:suite) do
|
|
8
|
+
MiniI18n.load_translations File.expand_path(__dir__ + '/fixtures/locales/*')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
config.before(:each) do
|
|
12
|
+
MiniI18n.locale = :en
|
|
13
|
+
MiniI18n.fallbacks = false
|
|
14
|
+
MiniI18n.available_locales = [:en, :es, :fr]
|
|
15
|
+
end
|
|
6
16
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mini_i18n
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- markets
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-08-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -66,7 +66,8 @@ dependencies:
|
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
|
-
description:
|
|
69
|
+
description: Minimalistic I18n library for Ruby. It supports localization, pluralization,
|
|
70
|
+
interpolations, fallbacks, nested keys and more.
|
|
70
71
|
email:
|
|
71
72
|
- srmarc.ai@gmail.com
|
|
72
73
|
executables: []
|
|
@@ -74,10 +75,13 @@ extensions: []
|
|
|
74
75
|
extra_rdoc_files: []
|
|
75
76
|
files:
|
|
76
77
|
- lib/mini_i18n.rb
|
|
78
|
+
- lib/mini_i18n/localization.rb
|
|
77
79
|
- lib/mini_i18n/utils.rb
|
|
78
80
|
- lib/mini_i18n/version.rb
|
|
79
81
|
- spec/fixtures/locales/en.yml
|
|
82
|
+
- spec/fixtures/locales/localization.yml
|
|
80
83
|
- spec/fixtures/locales/multiple.yml
|
|
84
|
+
- spec/localization_spec.rb
|
|
81
85
|
- spec/mini_i18n_spec.rb
|
|
82
86
|
- spec/spec_helper.rb
|
|
83
87
|
homepage: https://github.com/markets/mini_i18n
|
|
@@ -106,6 +110,8 @@ specification_version: 4
|
|
|
106
110
|
summary: Minimalistic I18n library for Ruby
|
|
107
111
|
test_files:
|
|
108
112
|
- spec/fixtures/locales/en.yml
|
|
113
|
+
- spec/fixtures/locales/localization.yml
|
|
109
114
|
- spec/fixtures/locales/multiple.yml
|
|
115
|
+
- spec/localization_spec.rb
|
|
110
116
|
- spec/mini_i18n_spec.rb
|
|
111
117
|
- spec/spec_helper.rb
|