Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: Added basic ActiveRecord backend
- Loading branch information
Theo Cushion
authored and
Sven Fuchs
committed
Nov 13, 2009
1 parent
0e7546d
commit 786632d
Showing
8 changed files
with
336 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
require 'i18n/backend/base' | ||
require 'i18n/backend/active_record/translation' | ||
require 'i18n/hash' | ||
|
||
module I18n | ||
module Backend | ||
class ActiveRecord < Base | ||
|
||
def reload! | ||
end | ||
|
||
def store_translations(locale, data) | ||
data.unwind.each{|key,v| | ||
Translation.create(:locale => locale.to_s, :key => key, :value => v) | ||
} | ||
end | ||
|
||
def available_locales | ||
Translation.find(:all, :select => 'DISTINCT locale').map{|t| t.locale} | ||
end | ||
|
||
protected | ||
|
||
def lookup(locale, key, scope = [], separator = I18n.default_separator) | ||
return unless key | ||
separator ||= "." | ||
flat_key = (Array(scope) + Array(key)).join( separator ) | ||
|
||
result = Translation.locale(locale).key(flat_key).find(:first) | ||
return result.value if result | ||
results = Translation.locale(locale).keys(flat_key, separator) | ||
if results.empty? | ||
return nil | ||
else | ||
chop_range = (flat_key.size + separator.size)..-1 | ||
return results.inject({}){|hash,r| | ||
hash[r.key.slice( chop_range )] = hash[r.value] | ||
hash | ||
}.wind | ||
end | ||
end | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
require 'active_record' | ||
require 'ruby2ruby' | ||
require 'parse_tree' | ||
require 'parse_tree_extensions' | ||
|
||
class Translation < ActiveRecord::Base | ||
|
||
attr_protected :proc | ||
serialize :value | ||
|
||
named_scope :locale, lambda {|locale| | ||
{ :conditions => {:locale => locale }} | ||
} | ||
|
||
named_scope :key, lambda { |key| | ||
{ :conditions => {:key => key} } | ||
} | ||
|
||
named_scope :keys, lambda { |key, separator| | ||
separator ||= I18n.default_separator | ||
{ :conditions => "key LIKE '#{key}#{separator}%'" } | ||
} | ||
|
||
def value=(v) | ||
case v | ||
when Proc | ||
write_attribute(:value, v.to_ruby) | ||
write_attribute(:proc, true) | ||
else | ||
write_attribute(:value, v) | ||
end | ||
end | ||
|
||
def value | ||
if proc | ||
Kernel.eval read_attribute( :value ) | ||
else | ||
read_attribute( :value ) | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
class Hash | ||
|
||
# >> {"a"=>{"b"=>{"c"=>"foo", "d"=>"bar"}, "c"=>"j"}, "q"=>"asd"}.unwind | ||
# => {"a.c"=>"j", "a.b.d"=>"bar", "q"=>"asd", "a.b.c"=>"foo"} | ||
def unwind(separator = ".", key = nil, start = {}) | ||
self.inject(start){|hash,k| | ||
expanded_key = [key, k[0]].compact.join( separator ) | ||
if k[1].is_a? Hash | ||
k[1].unwind(separator, expanded_key, hash) | ||
else | ||
hash[ expanded_key ] = k[1] | ||
end | ||
hash | ||
} | ||
end | ||
|
||
# >> {"a.b.c" => "foo", "a.b.d" => "bar", "a.c" => "j", "q" => "asd"}.wind | ||
# => {"a"=>{"b"=>{"c"=>"foo", "d"=>"bar"}, "c"=>"j"}, "q"=>"asd"} | ||
def wind(separator = ".", key = nil, start = {}) | ||
wound = Hash.new | ||
self.each {|key, value| | ||
keys = key.split( separator ) | ||
index = 0 | ||
keys.inject(wound){|h,v| | ||
index += 1 | ||
if index >= keys.size | ||
h[v.to_sym] = value | ||
break | ||
else | ||
h[v.to_sym] ||= {} | ||
end | ||
} | ||
} | ||
wound | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# encoding: utf-8 | ||
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper') | ||
require 'i18n/backend/active_record' | ||
|
||
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:") | ||
ActiveRecord::Schema.define(:version => 1) do | ||
create_table :translations do |t| | ||
t.string :locale | ||
t.string :key | ||
t.string :value | ||
t.boolean :proc | ||
end | ||
end | ||
|
||
class I18nActiveRecordBackendApiBasicsTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Base | ||
include Tests::Backend::Api::Basics | ||
end | ||
|
||
class I18nActiveRecordBackendApiTranslateTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Base | ||
include Tests::Backend::Api::Translation | ||
end | ||
|
||
class I18nActiveRecordBackendApiInterpolateTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Base | ||
include Tests::Backend::Api::Interpolation | ||
end | ||
|
||
class I18nActiveRecordBackendApiLambdaTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Base | ||
include Tests::Backend::Api::Lambda | ||
end | ||
|
||
class I18nActiveRecordBackendApiTranslateLinkedTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Base | ||
include Tests::Backend::Api::Link | ||
end | ||
|
||
class I18nActiveRecordBackendApiPluralizationTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Base | ||
include Tests::Backend::Api::Pluralization | ||
end | ||
|
||
class I18nActiveRecordBackendApiLocalizeDateTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Localization | ||
include Tests::Backend::Api::Localization::Date | ||
end | ||
|
||
class I18nActiveRecordBackendApiLocalizeDateTimeTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Localization | ||
include Tests::Backend::Api::Localization::DateTime | ||
end | ||
|
||
class I18nActiveRecordBackendApiLocalizeTimeTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Localization | ||
include Tests::Backend::Api::Localization::Time | ||
end | ||
|
||
class I18nActiveRecordBackendApiLocalizeLambdaTest < Test::Unit::TestCase | ||
include Tests::Backend::ActiveRecord::Setup::Localization | ||
include Tests::Backend::Api::Localization::Lambda | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
module Tests | ||
module Backend | ||
module ActiveRecord | ||
module Setup | ||
module Base | ||
def setup | ||
super | ||
I18n.locale = nil | ||
I18n.default_locale = :en | ||
I18n.backend = I18n::Backend::ActiveRecord.new | ||
backend_store_translations :en, :foo => {:bar => 'bar', :baz => 'baz'} | ||
end | ||
|
||
def teardown | ||
super | ||
Translation.destroy_all | ||
I18n.backend = nil | ||
end | ||
end | ||
|
||
module Localization | ||
include Base | ||
|
||
def setup | ||
super | ||
setup_datetime_translations | ||
setup_datetime_lambda_translations | ||
@old_timezone, ENV['TZ'] = ENV['TZ'], 'UTC' | ||
end | ||
|
||
def teardown | ||
super | ||
@old_timezone ? ENV['TZ'] = @old_timezone : ENV.delete('TZ') | ||
end | ||
|
||
def setup_datetime_translations | ||
backend_store_translations :de, { | ||
:date => { | ||
:formats => { | ||
:default => "%d.%m.%Y", | ||
:short => "%d. %b", | ||
:long => "%d. %B %Y", | ||
:long_ordinalized => lambda { |date, options| | ||
tz = " (#{options[:timezone]})" if options[:timezone] | ||
"#{date.day}ter %B %Y#{tz}" | ||
} | ||
}, | ||
:day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag), | ||
:abbr_day_names => %w(So Mo Di Mi Do Fr Sa), | ||
:month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil), | ||
:abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil), | ||
:order => [:day, :month, :year] | ||
}, | ||
:time => { | ||
:formats => { | ||
:default => "%a, %d. %b %Y %H:%M:%S %z", | ||
:short => "%d. %b %H:%M", | ||
:long => "%d. %B %Y %H:%M", | ||
:long_ordinalized => lambda { |date, options| | ||
tz = " (#{options[:timezone]})" if options[:timezone] | ||
"#{date.day}ter %B %Y, %H:%M Uhr#{tz}" | ||
} | ||
}, | ||
:am => 'am', | ||
:pm => 'pm' | ||
}, | ||
:datetime => { | ||
:distance_in_words => { | ||
:half_a_minute => 'half a minute', | ||
:less_than_x_seconds => { | ||
:one => 'less than 1 second', | ||
:other => 'less than {{count}} seconds' | ||
}, | ||
:x_seconds => { | ||
:one => '1 second', | ||
:other => '{{count}} seconds' | ||
}, | ||
:less_than_x_minutes => { | ||
:one => 'less than a minute', | ||
:other => 'less than {{count}} minutes' | ||
}, | ||
:x_minutes => { | ||
:one => '1 minute', | ||
:other => '{{count}} minutes' | ||
}, | ||
:about_x_hours => { | ||
:one => 'about 1 hour', | ||
:other => 'about {{count}} hours' | ||
}, | ||
:x_days => { | ||
:one => '1 day', | ||
:other => '{{count}} days' | ||
}, | ||
:about_x_months => { | ||
:one => 'about 1 month', | ||
:other => 'about {{count}} months' | ||
}, | ||
:x_months => { | ||
:one => '1 month', | ||
:other => '{{count}} months' | ||
}, | ||
:about_x_years => { | ||
:one => 'about 1 year', | ||
:other => 'about {{count}} year' | ||
}, | ||
:over_x_years => { | ||
:one => 'over 1 year', | ||
:other => 'over {{count}} years' | ||
} | ||
} | ||
} | ||
} | ||
end | ||
|
||
def setup_datetime_lambda_translations | ||
backend_store_translations 'ru', { | ||
:date => { | ||
:'day_names' => lambda { |key, options| | ||
(options[:format] =~ /^%A/) ? | ||
%w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) : | ||
%w(воскресенье понедельник вторник среда четверг пятница суббота) | ||
}, | ||
:'abbr_day_names' => %w(Вс Пн Вт Ср Чт Пт Сб), | ||
:'month_names' => lambda { |key, options| | ||
(options[:format] =~ /(%d|%e)(\s*)?(%B)/) ? | ||
%w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) : | ||
%w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil) | ||
}, | ||
:'abbr_month_names' => lambda { |key, options| | ||
(options[:format] =~ /(%d|%e)(\s*)(%b)/) ? | ||
%w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) : | ||
%w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil) | ||
}, | ||
}, | ||
:time => { | ||
:am => "утра", | ||
:pm => "вечера" | ||
} | ||
} | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters