mini_i18n 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|