Permalink
Browse files

Merge pull request #92 from twitter/global_locale_setter

Adding a global locale setter.
  • Loading branch information...
2 parents e4fdb37 + c33cb9b commit 1b959dc963101a2aff6ef5e1315f36a99fd11d1d @camertron camertron committed Jan 12, 2013
View
@@ -613,7 +613,7 @@ TwitterCldr.convert_locale(:msa) # :ms
TwitterCldr.convert_locale(:ms) # :ms
```
-There are a few functions in TwitterCLDR that don't require a locale code, and instead use the default locale by calling `TwitterCldr.get_locale`. The `get_locale` function defers to `FastGettext.locale` when the FastGettext library is available, and falls back on :en (English) when it's not. (Twitter uses the FastGettext gem to retrieve translations efficiently in Ruby).
+There are a few functions in TwitterCLDR that don't require a locale code, and instead use the default locale by calling `TwitterCldr.locale`. The `locale` function defers to `FastGettext.locale` when the FastGettext library is available, and falls back on :en (English) when it's not. (Twitter uses the FastGettext gem to retrieve translations efficiently in Ruby).
```ruby
TwitterCldr.get_locale # will return :en
View
@@ -54,23 +54,53 @@ module TwitterCldr
class << self
+ attr_writer :locale
+
def resources
@resources ||= TwitterCldr::Resources::Loader.new
end
- def get_locale
- if defined?(FastGettext)
- locale = FastGettext.locale
- locale = DEFAULT_LOCALE if locale.to_s.empty?
- else
- locale = DEFAULT_LOCALE
+ def locale
+ locale = supported_locale?(@locale) ? @locale : find_fallback
+ locale = DEFAULT_LOCALE if locale.to_s.empty?
+ (supported_locale?(locale) ? locale : DEFAULT_LOCALE).to_sym
+ end
+
+ def with_locale(locale)
+ raise "Unsupported locale" unless supported_locale?(locale)
+
+ begin
+ old_locale = @locale
+ @locale = locale
+ result = yield
+ ensure
+ @locale = old_locale
+ result
end
+ end
- (supported_locale?(locale) ? locale : DEFAULT_LOCALE).to_sym
+ def register_locale_fallback(proc_or_locale)
+ case proc_or_locale
+ when Symbol, String, Proc
+ locale_fallbacks << proc_or_locale
+ else
+ raise "A locale fallback must be of type String, Symbol, or Proc."
+ end
+ nil
+ end
+
+ def reset_locale_fallbacks
+ locale_fallbacks.clear
+ TwitterCldr.register_locale_fallback(lambda { I18n.locale if defined?(I18n) && I18n.respond_to?(:locale) })
+ TwitterCldr.register_locale_fallback(lambda { FastGettext.locale if defined?(FastGettext) && FastGettext.respond_to?(:locale) })
+ end
+
+ def locale_fallbacks
+ @locale_fallbacks ||= []
end
def convert_locale(locale)
- locale = locale.to_sym
+ locale = locale.to_sym if locale.respond_to?(:to_sym)
TWITTER_LOCALE_MAP.fetch(locale, locale)
end
@@ -86,8 +116,29 @@ def supported_locales
def supported_locale?(locale)
!!locale && supported_locales.include?(convert_locale(locale))
end
+
+ protected
+
+ def find_fallback
+ locale_fallbacks.reverse_each do |fallback|
+ result = if fallback.is_a?(Proc)
+ begin
+ fallback.call
+ rescue
+ nil
+ end
+ else
+ fallback
+ end
+ return result if result
+ end
+ nil
+ end
+
end
end
+TwitterCldr.reset_locale_fallbacks
+
require 'twitter_cldr/core_ext'
@@ -11,7 +11,7 @@ module Rules
class << self
def all
- all_for(TwitterCldr.get_locale)
+ all_for(TwitterCldr.locale)
end
def all_for(locale)
@@ -20,7 +20,7 @@ def all_for(locale)
nil
end
- def rule_for(number, locale = TwitterCldr.get_locale)
+ def rule_for(number, locale = TwitterCldr.locale)
get_resource(locale)[:rule].call(number)
rescue
:other
@@ -27,7 +27,7 @@ def formatter_const
def self.localize(klass)
klass.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
- def localize(locale = TwitterCldr.get_locale, options = {})
+ def localize(locale = TwitterCldr.locale, options = {})
#{self}.new(self, locale, options)
end
LOCALIZE
@@ -8,7 +8,7 @@ module Localized
class LocalizedTimespan < LocalizedObject
def initialize(seconds, options = {})
- super(seconds, options[:locale] || TwitterCldr.get_locale, options)
+ super(seconds, options[:locale] || TwitterCldr.locale, options)
end
def to_s(options = {})
@@ -32,7 +32,7 @@ class Calendar
attr_reader :locale, :calendar_type
- def initialize(locale = TwitterCldr.get_locale, calendar_type = TwitterCldr::DEFAULT_CALENDAR_TYPE)
+ def initialize(locale = TwitterCldr.locale, calendar_type = TwitterCldr::DEFAULT_CALENDAR_TYPE)
@locale = TwitterCldr.convert_locale(locale)
@calendar_type = calendar_type
end
@@ -10,7 +10,7 @@ module Languages
class << self
def all
- all_for(TwitterCldr.get_locale)
+ all_for(TwitterCldr.locale)
end
def all_for(code)
@@ -20,16 +20,16 @@ def all_for(code)
end
def from_code(code)
- from_code_for_locale(code, TwitterCldr.get_locale)
+ from_code_for_locale(code, TwitterCldr.locale)
end
- def from_code_for_locale(code, locale = TwitterCldr.get_locale)
+ def from_code_for_locale(code, locale = TwitterCldr.locale)
get_resource(locale)[:languages][TwitterCldr.convert_locale(code)]
rescue
nil
end
- def translate_language(language, source_locale = :en, dest_locale = TwitterCldr.get_locale)
+ def translate_language(language, source_locale = :en, dest_locale = TwitterCldr.locale)
lang_code = get_resource(source_locale)[:languages].detect { |_, val| val.downcase == language.downcase }.first
get_resource(dest_locale)[:languages][lang_code] if lang_code
rescue
@@ -9,7 +9,7 @@ module Numbers
class << self
- def symbols(locale = TwitterCldr.get_locale)
+ def symbols(locale = TwitterCldr.locale)
get_resource(TwitterCldr.convert_locale(locale))[:symbols] rescue nil
end
@@ -10,7 +10,7 @@ module Territories
class << self
def all
- all_for(TwitterCldr.get_locale)
+ all_for(TwitterCldr.locale)
end
def all_for(code)
@@ -20,15 +20,15 @@ def all_for(code)
end
def from_territory_code(territory_code)
- from_territory_code_for_locale(territory_code, TwitterCldr.get_locale)
+ from_territory_code_for_locale(territory_code, TwitterCldr.locale)
end
# Returns how to say a given territory in a given locale.
#
# This method does not work for three-digit United Nation "area
# codes" (UN M.49; for example, 014 for Eastern Africa and 419 for Latin
# America).
- def from_territory_code_for_locale(territory_code, locale = TwitterCldr.get_locale)
+ def from_territory_code_for_locale(territory_code, locale = TwitterCldr.locale)
get_resource(locale)[:territories][TwitterCldr::Utils::Territories.normalize_territory_code(territory_code)]
rescue
nil
@@ -39,7 +39,7 @@ def from_territory_code_for_locale(territory_code, locale = TwitterCldr.get_loca
# This method does not work for three-digit United Nation "area
# codes" (UN M.49; for example, 014 for Eastern Africa and 419 for Latin
# America).
- def translate_territory(territory_name, source_locale = :en, dest_locale = TwitterCldr.get_locale)
+ def translate_territory(territory_name, source_locale = :en, dest_locale = TwitterCldr.locale)
territory_code, _ = get_resource(source_locale)[:territories].find do |_, other_territory_name|
other_territory_name.downcase == territory_name.downcase
end
@@ -60,7 +60,7 @@
describe "#all" do
it "gets rules for the default locale (usually supplied by FastGettext)" do
- mock(TwitterCldr).get_locale { :ru }
+ mock(TwitterCldr).locale { :ru }
Rules.all.should =~ [:one, :few, :many, :other]
end
end
@@ -81,7 +81,7 @@ def formatter_const
end
it 'uses default locale and empty options hash by default' do
- mock(LocalizedClass).new(localizable_object, TwitterCldr.get_locale, {})
+ mock(LocalizedClass).new(localizable_object, TwitterCldr.locale, {})
localizable_object.localize
end
end
@@ -12,7 +12,7 @@
describe "#as_language_code" do
it "returns the correct localized language from the symbol" do
:es.localize.as_language_code.should == "Spanish"
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
:es.localize.as_language_code.should == "español"
end
View
@@ -273,8 +273,9 @@ def spaces(str)
end
it "verifies locale defaults" do
- TwitterCldr.get_locale.should == :en
+ TwitterCldr.locale.should == :en
+ TwitterCldr.locale = nil
FastGettext.locale = "ru"
- TwitterCldr.get_locale.should == :ru
+ TwitterCldr.locale.should == :ru
end
end
@@ -18,7 +18,7 @@
describe '#initialize' do
it 'returns calendar for default locale and type' do
- stub(TwitterCldr).get_locale { :fr }
+ stub(TwitterCldr).locale { :fr }
cal = Calendar.new
cal.locale.should == :fr
@@ -21,14 +21,14 @@
Languages.translate_language("RUSSIAN", :en, :es).should match_normalized("ruso")
end
- it "defaults the destination language to English (or whatever FastGettext.locale is)" do
+ it "defaults the destination language to English (or whatever the global locale is)" do
Languages.translate_language("Ruso", :es).should match_normalized("Russian")
Languages.translate_language("русский", :ru).should match_normalized("Russian")
end
it "defaults source and destination language to English if not given" do
Languages.translate_language("Russian").should match_normalized("Russian")
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
Languages.translate_language("Russian").should match_normalized("ruso")
end
@@ -53,7 +53,7 @@
it "should return the language in the default locale for the given locale code" do
Languages.from_code(:es).should match_normalized("Spanish")
Languages.from_code(:ru).should match_normalized("Russian")
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
Languages.from_code(:es).should match_normalized("español")
end
end
@@ -78,7 +78,7 @@
langs[:ru].should match_normalized("Russian")
langs[:de].should match_normalized("German")
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
langs = Languages.all
langs.should be_a(Hash)
langs[:ru].should match_normalized("ruso")
@@ -12,7 +12,7 @@
let(:symbols) { { :nan => 'NaN', :minus_sign => '-' } }
it 'returns numerical symbols for default locale' do
- stub(TwitterCldr).get_locale { :jp }
+ stub(TwitterCldr).locale { :jp }
stub(TwitterCldr).get_locale_resource(:jp, :numbers) { { :jp => { :numbers => { :symbols => symbols } } } }
TwitterCldr::Shared::Numbers.symbols.should == symbols
end
@@ -32,14 +32,14 @@
Territories.translate_territory("RUSSIA", :en, :es).should match_normalized("Rusia")
end
- it "defaults the destination language to English (or whatever FastGettext.locale is)" do
+ it "defaults the destination language to English (or whatever the global locale is)" do
Territories.translate_territory("Rusia", :es).should match_normalized("Russia")
Territories.translate_territory("Россия", :ru).should match_normalized("Russia")
end
it "defaults source and destination language to English if not given" do
Territories.translate_territory("Russia").should match_normalized("Russia")
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
Territories.translate_territory("Russia").should match_normalized("Rusia")
end
@@ -73,7 +73,7 @@
it "should return the language in the default locale for the given locale code" do
Territories.from_territory_code(:ES).should match_normalized("Spain")
Territories.from_territory_code(:RU).should match_normalized("Russia")
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
Territories.from_territory_code(:ES).should match_normalized("España")
end
end
@@ -98,7 +98,7 @@
territories[:ru].should match_normalized("Russia")
territories[:de].should match_normalized("Germany")
- FastGettext.locale = :es
+ TwitterCldr.locale = :es
territories = Territories.all
territories.should be_a(Hash)
territories[:ru].should match_normalized("Rusia")
View
@@ -21,8 +21,22 @@ def locale
@@locale
end
- def locale=(value)
- @@locale = value
+ def locale=(new_locale)
+ @@locale = new_locale
+ end
+ end
+end
+
+class I18n
+ class << self
+ @@locale = :en
+
+ def locale
+ @@locale
+ end
+
+ def locale=(new_locale)
+ @@locale = new_locale
end
end
end
@@ -35,7 +49,10 @@ def locale=(value)
config.filter_run_excluding(:slow => true) unless ENV['FULL_SPEC']
config.before(:each) do
+ TwitterCldr.reset_locale_fallbacks
+ TwitterCldr.locale = :en
FastGettext.locale = :en
+ I18n.locale = :en
end
end
Oops, something went wrong.

0 comments on commit 1b959dc

Please sign in to comment.