Skip to content

Commit

Permalink
Clean up locale fallback code
Browse files Browse the repository at this point in the history
It was breaking on locales with more than two segments (e.g., `zh-Hant-HK`)

Beyond that, I pulled out the fallback code and exposed it so that downstream consumers can use it too.
I structured it in a similar manner as `ruby-i18n`'s [`I18n::Locale::Fallbacks`](https://github.com/ruby-i18n/i18n/blob/535459ad1201e7cc97a071bd5d9f0e1d5406069e/lib/i18n/locale/fallbacks.rb).

I also changed the keys and values in `ParentLocales` to be symbols, which simplifies the code.

It's still not fully correct for locales that contain scripts (e.g., `ff-Adlm-GH`).
That will be a different commit.
  • Loading branch information
movermeyer committed Dec 9, 2021
1 parent e0576c2 commit 53f8ae2
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Sort the exported data by key, [#82](https://github.com/ruby-i18n/ruby-cldr/pull/82)
- Prune empty hashes / files before outputting, [#86](https://github.com/ruby-i18n/ruby-cldr/pull/86)
- Re-add the `ParentLocales` component, this time as a shared component, [#91](https://github.com/ruby-i18n/ruby-cldr/pull/91)
- Changed the keys and values of `ParentLocales` component to be symbols, [#101](https://github.com/ruby-i18n/ruby-cldr/pull/101)
- Fixed bug with fallbacks for locales that had more than two segments, [#101](https://github.com/ruby-i18n/ruby-cldr/pull/101)

---

Expand Down
9 changes: 8 additions & 1 deletion lib/cldr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,12 @@
module Cldr
autoload :Data, 'cldr/data'
autoload :Export, 'cldr/export'
autoload :Locale, 'cldr/locale'
autoload :Format, 'cldr/format'
end

class << self
def fallbacks
@@fallbacks ||= Cldr::Locale::Fallbacks.new
end
end
end
19 changes: 3 additions & 16 deletions lib/cldr/export.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,25 +135,12 @@ def locales(locale, component, options)
locale = to_i18n(locale)

locales = if options[:merge]
defined_parents = Cldr::Export::Data::ParentLocales.new

ancestry = [locale.to_s]
loop do
if defined_parents[ancestry.last]
ancestry << defined_parents[ancestry.last]
elsif I18n::Locale::Tag.tag(ancestry.last).self_and_parents.count > 1
ancestry << I18n::Locale::Tag.tag(ancestry.last).self_and_parents.last
else
break
end
end

ancestry.map(&:to_sym)
Cldr.fallbacks[locale]
else
[locale]
[locale, :root]
end

locales << :root if should_merge_root?(locale, component, options)
locales.pop unless should_merge_root?(locale, component, options)
locales
end

Expand Down
4 changes: 2 additions & 2 deletions lib/cldr/export/data/parent_locales.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def initialize(_ = nil)
doc = File.open(path) { |file| Nokogiri::XML(file) }

doc.xpath('//parentLocales/parentLocale').each do |node|
parent = Cldr::Export.to_i18n(node.attr('parent')).to_s
locales = node.attr('locales').split(' ').map {|locale| Cldr::Export.to_i18n(locale) }.map(&:to_s)
parent = Cldr::Export.to_i18n(node.attr('parent'))
locales = node.attr('locales').split(' ').map {|locale| Cldr::Export.to_i18n(locale) }

locales.each do |locale|
self[locale] = parent
Expand Down
22 changes: 22 additions & 0 deletions lib/cldr/locale/fallbacks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Cldr
module Locale
class Fallbacks < Hash
def [](locale)
defined_parents = Cldr::Export::Data::ParentLocales.new

ancestry = [locale]
loop do
if defined_parents[ancestry.last]
ancestry << defined_parents[ancestry.last]
elsif I18n::Locale::Tag.tag(ancestry.last).parents.count > 0
ancestry << I18n::Locale::Tag.tag(ancestry.last).parents.first.to_sym
else
break
end
end
ancestry << :root unless ancestry.last == :root
store(locale, ancestry)
end
end
end
end
18 changes: 18 additions & 0 deletions test/locale/fallbacks_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# encoding: utf-8

require File.expand_path(File.join(File.dirname(__FILE__) + '/../test_helper'))

class TestFallbacks < Test::Unit::TestCase
test "fallbacks does basic hyphen chopping" do
assert_equal [:root], Cldr.fallbacks[:root]
assert_equal [:en, :root], Cldr.fallbacks[:en]
assert_equal [:"fr-CA", :fr, :root], Cldr.fallbacks[:"fr-CA"]
assert_equal [:"zh-Hant-HK", :"zh-Hant", :root], Cldr.fallbacks[:"zh-Hant-HK"]
end

test "fallbacks observe explicit parent overrides" do
assert_equal [:"az-Arab", :root], Cldr.fallbacks[:"az-Arab"]
assert_equal [:"en-CH", :"en-150", :"en-001", :en, :root], Cldr.fallbacks[:"en-CH"]
assert_equal [:"zh-Hant", :root], Cldr.fallbacks[:"zh-Hant"]
end
end

0 comments on commit 53f8ae2

Please sign in to comment.