Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,27 +248,38 @@ And then, you get:

You can also use the `MiniI18n.l()` (or the long version `MiniI18n.localize()` or the global shorcut `L()`) method to localize your dates, time and numbers.

`MiniI18n` provides built-in localization defaults for common languages:
- `:en` - English
- `:es` - Spanish
- `:fr` - French
- `:de` - German
- `:pt` - Portuguese
- `:it` - Italian
- `:nl` - Dutch
- `:zh` - Chinese
- `:ja` - Japanese

These defaults include proper date/time formats, day and month names, and number formatting that follows each language's conventions. You can check a full example of all necessary and useful keys [in this folder](lib/mini_i18n/locales/).

#### Dates and time

It uses `strftime` under the hood. You should provide your localizations using the following format:
It uses `strftime` under the hood. You can customize the defaults using the following format:

```yaml
en:
date:
formats:
default: "%A %d, %B, %Y"
short: "%d %b %y"
default: "%A %d, %b %Y"
short: "%d %B, %y"
```

```ruby
>> MiniI18n.l(Date.new(2018, 8, 15))
=> "Wednesday 15, August, 2018"
=> "Wednesday 15, Aug 2018"
>> MiniI18n.l(Date.new(2018, 8, 15), format: :short)
=> "15 Aug 18"
=> "15 August, 18"
```

You can check a full example of all necessary and useful keys [in this file](spec/fixtures/locales/localization.yml).

#### Numbers

To localize your numbers, you can provide the following keys:
Expand Down
10 changes: 10 additions & 0 deletions lib/mini_i18n.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ def available_locales

def available_locales=(new_locales)
@@available_locales = Array(new_locales).map(&:to_s)

# Load built-in localization defaults
@@available_locales.each do |locale|
default_locale_path = File.join(File.dirname(__FILE__), "mini_i18n", "locales", "#{locale}.yml")
if File.exist?(default_locale_path)
YAML.load_file(default_locale_path).each do |loc, translations|
add_translations(loc, translations)
end
end
end
end

def translations
Expand Down
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/de.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
de:
date:
formats:
default: "%A, %-d. %B %Y"
short: "%-d.%-m.%y"
day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
month_names: [Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
abbr_month_names: [Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
time:
formats:
default: "%a, %-d. %B %Y - %H:%M"
short: "%-d.%-m.%y - %H:%M"
number:
format:
delimiter: '.'
separator: ','
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,3 @@ en:
format:
delimiter: ','
separator: '.'
as:
currency: '%{number} $'
distance: 'Distance: %{number} miles'
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/es.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
es:
date:
formats:
default: "%-d/%-m/%Y"
short: "%-d %b %y"
day_names: [domingo, lunes, martes, miércoles, jueves, viernes, sábado]
abbr_day_names: [dom, lun, mar, mié, jue, vie, sáb]
month_names: [enero, febrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre]
abbr_month_names: [ene, feb, mar, abr, may, jun, jul, ago, sep, oct, nov, dic]
time:
formats:
default: "%a %-d de %B de %Y - %H:%M"
short: "%-d %b %y - %H:%M"
number:
format:
delimiter: '.'
separator: ','
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/fr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fr:
date:
formats:
default: "%A %-d %B %Y"
short: "%-d %b %y"
day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
month_names: [janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre]
abbr_month_names: [janv, févr, mars, avr, mai, juin, juil, août, sept, oct, nov, déc]
time:
formats:
default: "%a %-d %B %Y - %H:%M"
short: "%-d %b %y - %H:%M"
number:
format:
delimiter: ' '
separator: ','
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/it.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
it:
date:
formats:
default: "%A %-d %B %Y"
short: "%-d/%m/%y"
day_names: [domenica, lunedì, martedì, mercoledì, giovedì, venerdì, sabato]
abbr_day_names: [dom, lun, mar, mer, gio, ven, sab]
month_names: [gennaio, febbraio, marzo, aprile, maggio, giugno, luglio, agosto, settembre, ottobre, novembre, dicembre]
abbr_month_names: [gen, feb, mar, apr, mag, giu, lug, ago, set, ott, nov, dic]
time:
formats:
default: "%a %-d %B %Y - %H:%M"
short: "%-d/%m/%y - %H:%M"
number:
format:
delimiter: '.'
separator: ','
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/ja.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
ja:
date:
formats:
default: "%Y年%-m月%-d日"
short: "%y年%-m月%-d日"
day_names: [日曜日, 月曜日, 火曜日, 水曜日, 木曜日, 金曜日, 土曜日]
abbr_day_names: [日, 月, 火, 水, 木, 金, 土]
month_names: [1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
abbr_month_names: [1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
time:
formats:
default: "%Y年%-m月%-d日 %H:%M"
short: "%y年%-m月%-d日 %H:%M"
number:
format:
delimiter: ','
separator: '.'
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/nl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
nl:
date:
formats:
default: "%A %-d %B %Y"
short: "%-d-%-m-%y"
day_names: [zondag, maandag, dinsdag, woensdag, donderdag, vrijdag, zaterdag]
abbr_day_names: [zo, ma, di, wo, do, vr, za]
month_names: [januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november, december]
abbr_month_names: [jan, feb, mrt, apr, mei, jun, jul, aug, sep, okt, nov, dec]
time:
formats:
default: "%a %-d %B %Y - %H:%M"
short: "%-d-%-m-%y - %H:%M"
number:
format:
delimiter: '.'
separator: ','
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/pt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pt:
date:
formats:
default: "%A, %-d de %B de %Y"
short: "%-d/%m/%y"
day_names: [domingo, segunda-feira, terça-feira, quarta-feira, quinta-feira, sexta-feira, sábado]
abbr_day_names: [dom, seg, ter, qua, qui, sex, sáb]
month_names: [janeiro, fevereiro, março, abril, maio, junho, julho, agosto, setembro, outubro, novembro, dezembro]
abbr_month_names: [jan, fev, mar, abr, mai, jun, jul, ago, set, out, nov, dez]
time:
formats:
default: "%a, %-d de %B de %Y - %H:%M"
short: "%-d/%m/%y - %H:%M"
number:
format:
delimiter: '.'
separator: ','
17 changes: 17 additions & 0 deletions lib/mini_i18n/locales/zh.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
zh:
date:
formats:
default: "%Y年%-m月%-d日"
short: "%y年%-m月%-d日"
day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
month_names: [一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
abbr_month_names: [1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
time:
formats:
default: "%Y年%-m月%-d日 %H:%M"
short: "%y年%-m月%-d日 %H:%M"
number:
format:
delimiter: ','
separator: '.'
2 changes: 1 addition & 1 deletion lib/mini_i18n/localization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def localize_number(number, options)
locale = options[:locale]
delimiter = MiniI18n.t("number.format.delimiter", locale: locale)
separator = MiniI18n.t("number.format.separator", locale: locale)
integer, fractional = number.to_s.split(separator)
integer, fractional = number.to_s.split('.')

integer.to_s.gsub!(DELIMITER_REGEX) do |match|
"#{match}#{delimiter}"
Expand Down
69 changes: 69 additions & 0 deletions spec/default_locales_integration_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
RSpec.describe "Default Locales Integration" do
let(:date) { Date.new(2023, 12, 25) }
let(:time) { Time.new(2023, 12, 25, 14, 30) }
let(:number) { 1234.56 }

before(:each) do
@original_translations = MiniI18n.translations.dup
@original_available_locales = MiniI18n.available_locales.dup
MiniI18n.available_locales = [:en, :es, :fr, :de, :pt, :it, :nl, :zh, :ja]
end

after(:each) do
MiniI18n.translations.clear
MiniI18n.translations.merge!(@original_translations)
MiniI18n.available_locales = @original_available_locales
end

describe "Date localization" do
it "formats dates according to each locale" do
expect(MiniI18n.l(date, locale: :en)).to eq("Monday 25, December, 2023")
expect(MiniI18n.l(date, locale: :es)).to eq("25/12/2023")
expect(MiniI18n.l(date, locale: :fr)).to eq("lundi 25 décembre 2023")
expect(MiniI18n.l(date, locale: :de)).to eq("Montag, 25. Dezember 2023")
expect(MiniI18n.l(date, locale: :pt)).to eq("segunda-feira, 25 de dezembro de 2023")
expect(MiniI18n.l(date, locale: :it)).to eq("lunedì 25 dicembre 2023")
expect(MiniI18n.l(date, locale: :nl)).to eq("maandag 25 december 2023")
expect(MiniI18n.l(date, locale: :zh)).to eq("2023年12月25日")
expect(MiniI18n.l(date, locale: :ja)).to eq("2023年12月25日")
end

it "formats short dates according to each locale" do
expect(MiniI18n.l(date, format: :short, locale: :en)).to eq("25 Dec 23")
expect(MiniI18n.l(date, format: :short, locale: :es)).to eq("25 dic 23")
expect(MiniI18n.l(date, format: :short, locale: :fr)).to eq("25 déc 23")
expect(MiniI18n.l(date, format: :short, locale: :de)).to eq("25.12.23")
expect(MiniI18n.l(date, format: :short, locale: :pt)).to eq("25/12/23")
expect(MiniI18n.l(date, format: :short, locale: :it)).to eq("25/12/23")
expect(MiniI18n.l(date, format: :short, locale: :nl)).to eq("25-12-23")
expect(MiniI18n.l(date, format: :short, locale: :zh)).to eq("23年12月25日")
expect(MiniI18n.l(date, format: :short, locale: :ja)).to eq("23年12月25日")
end
end

describe "Time localization" do
it "formats times according to each locale" do
expect(MiniI18n.l(time, locale: :en)).to eq("Mon 25, December, 2023 - 14:30")
expect(MiniI18n.l(time, locale: :es)).to eq("lun 25 de diciembre de 2023 - 14:30")
expect(MiniI18n.l(time, locale: :fr)).to eq("lun 25 décembre 2023 - 14:30")
expect(MiniI18n.l(time, locale: :de)).to eq("Mo, 25. Dezember 2023 - 14:30")
expect(MiniI18n.l(time, locale: :pt)).to eq("seg, 25 de dezembro de 2023 - 14:30")
expect(MiniI18n.l(time, locale: :it)).to eq("lun 25 dicembre 2023 - 14:30")
expect(MiniI18n.l(time, locale: :nl)).to eq("ma 25 december 2023 - 14:30")
end
end

describe "Number localization" do
it "formats numbers according to each locale" do
expect(MiniI18n.l(number, locale: :en)).to eq("1,234.56")
expect(MiniI18n.l(number, locale: :es)).to eq("1.234,56")
expect(MiniI18n.l(number, locale: :fr)).to eq("1 234,56")
expect(MiniI18n.l(number, locale: :de)).to eq("1.234,56")
expect(MiniI18n.l(number, locale: :pt)).to eq("1.234,56")
expect(MiniI18n.l(number, locale: :it)).to eq("1.234,56")
expect(MiniI18n.l(number, locale: :nl)).to eq("1.234,56")
expect(MiniI18n.l(number, locale: :zh)).to eq("1,234.56")
expect(MiniI18n.l(number, locale: :ja)).to eq("1,234.56")
end
end
end
6 changes: 5 additions & 1 deletion spec/fixtures/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ en:
notifications:
zero: 'no unread notifications'
one: '1 unread notification'
other: '%{count} unread notifications'
other: '%{count} unread notifications'
number:
as:
currency: '%{number} $'
distance: 'Distance -> %{number} miles'
6 changes: 3 additions & 3 deletions spec/localization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@

it 'as' do
expect(MiniI18n.l(9000, as: :currency)).to eq '9,000 $'
expect(MiniI18n.l(9000, as: :currency, locale: :es)).to eq '9000 €'
expect(MiniI18n.l(125.5, as: :distance)).to eq 'Distance: 125.5 miles'
expect(MiniI18n.l(9000, as: :currency, locale: :es)).to eq '9.000 €'
expect(MiniI18n.l(125.5, as: :distance)).to eq 'Distance -> 125.5 miles'
end
end
end
end