r18n-core 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.4.4 (Frank)
2
+ * Use before filter to lazy set I18n object in Sinatra extension.
3
+ * Set I18n object to thread (by Simon Hafner).
4
+ * Add to l Rails helper R18n syntax.
5
+ * Add common helpers.
6
+ * Clear cache in R18n.reset.
7
+ * Clean up code and fix bug (by Akzhan Abdulin).
8
+ * Add Thai locale (by Felix Hanley).
9
+
1
10
  == 0.4.3 (Flange)
2
11
  * Add R18n style methods to Rails controllers.
3
12
  * Fix for non-string translations in Rails I18n.
data/README.rdoc CHANGED
@@ -143,6 +143,24 @@ Sinatra, Merb and desktop applications.
143
143
 
144
144
  == Usage
145
145
 
146
+ To add i18n support to your app, you can use special plugin for your
147
+ environment: <tt>r18n-rails</tt>, <tt>sinatra-r18n</tt> or
148
+ <tt>r18n-desktop</tt>.
149
+
150
+ If you develop you own plugin or want to use only core gem, you must to create
151
+ I18n object and set to global variable by <tt>R18n.set</tt> or to current thread
152
+ by <tt>R18n.thread_set</tt>:
153
+
154
+ R18n.set(R18n::I18n.new('en', 'path/to/translations'))
155
+
156
+ You can add helpers to access to current I18n object:
157
+
158
+ include R18n::Helpers
159
+
160
+ t.yes #=> "Yes"
161
+ l Time.now, :human #=> "now"
162
+ r18n.locale.code #=> "en"
163
+
146
164
  === Translation
147
165
 
148
166
  Translation files use YAML format and has name like en.yml (English) or
data/base/th.yml ADDED
@@ -0,0 +1,19 @@
1
+ ok: OK
2
+ save: บันทึก
3
+ cancel: ยกเลิก
4
+ 'yes': ใช่
5
+ 'no': ไม่ใช่
6
+ exit: ออก จาก
7
+ delete: ลบ
8
+
9
+ human_time:
10
+ after_days: หลงจาก %1 วัน
11
+ tomorrow: พรุ่งนี้
12
+ after_hours: หลงจาก %1 ชั่วโมง
13
+ after_minutes: หลงจาก %1 นาที
14
+ now: ตอน นี้
15
+ today: วัน นี้
16
+ minutes_ago: %1 นาที ที่ ผ่าน มา
17
+ hours_ago: %1 ชั่วโมง ที่ ผ่าน มา
18
+ yesterday: เมื่อ วาน
19
+ days_ago: %1 วัน ที่ ผ่าน มา
data/lib/r18n-core.rb CHANGED
@@ -33,10 +33,12 @@ require dir + 'filters'
33
33
  require dir + 'translation'
34
34
  require dir + 'yaml_loader'
35
35
  require dir + 'i18n'
36
+ require dir + 'helpers'
36
37
 
37
38
  module R18n
38
39
  class << self
39
- # Set I18n object to current thread.
40
+
41
+ # Set I18n object globally.
40
42
  def set(i18n = nil, &block)
41
43
  if block_given?
42
44
  @setter = block
@@ -45,10 +47,32 @@ module R18n
45
47
  @i18n = i18n
46
48
  end
47
49
  end
48
-
50
+
51
+ # Set I18n object to current thread.
52
+ def thread_set(i18n = nil, &block)
53
+ if block_given?
54
+ Thread.current[:r18n_setter] = block
55
+ Thread.current[:r18n_i18n] = nil
56
+ else
57
+ Thread.current[:r18n_i18n] = i18n
58
+ end
59
+ end
60
+
49
61
  # Get I18n object for current thread.
50
62
  def get
51
- @i18n ||= (@setter.call if @setter)
63
+ (thread[:r18n_i18n] ||= ((block = thread[:r18n_setter]) && block.call)) ||
64
+ (@i18n ||= (@setter && @setter.call))
65
+ end
66
+
67
+ # Delete I18n object from current thread and global variable.
68
+ def reset
69
+ thread[:r18n_i18n] = thread[:r18n_setter] = @i18n = @setter = nil
70
+ self.cache = {}
71
+ end
72
+
73
+ # Get the current thread.
74
+ def thread
75
+ Thread.current
52
76
  end
53
77
 
54
78
  # Default loader class, which will be used if you didn’t send loader to
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ =begin
3
+ Mixin with common methods.
4
+
5
+ Copyright (C) 2010 Andrey “A.I.” Sitnik <andrey@sitnik.ru>
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU Lesser General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public License
18
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ =end
20
+
21
+ module R18n
22
+ # Useful aliases. Set I18n object before use them:
23
+ #
24
+ # R18n.set R18n::I18n.new('en')
25
+ #
26
+ # t.ok #=> "OK"
27
+ # l Time.now, :human #=> "now"
28
+ # r18n.locale.code #=> "en"
29
+ module Helpers
30
+ # Get current I18n object.
31
+ def r18n
32
+ R18n.get
33
+ end
34
+ alias i18n r18n
35
+
36
+ # Translate message. Alias for <tt>r18n.t</tt>.
37
+ def t(*params)
38
+ R18n.get.t(*params)
39
+ end
40
+
41
+ # Localize object. Alias for <tt>r18n.l</tt>.
42
+ def l(*params)
43
+ R18n.get.l(*params)
44
+ end
45
+ end
46
+ end
@@ -267,16 +267,6 @@ module R18n
267
267
  @translation
268
268
  end
269
269
 
270
- # Short and pretty way to get translation by method name. If translation
271
- # has name like object methods (+new+, +to_s+, +methods+) use <tt>[]</tt>
272
- # method to access.
273
- #
274
- # Translation can contain variable part. Just set is as <tt>%1</tt>,
275
- # <tt>%2</tt>, etc in translations file and set values as methods params.
276
- def method_missing(name, *params)
277
- @translation.send(name, *params)
278
- end
279
-
280
270
  # Return translation with special +name+.
281
271
  #
282
272
  # Translation can contain variable part. Just set is as <tt>%1</tt>,
@@ -284,5 +274,6 @@ module R18n
284
274
  def [](name, *params)
285
275
  @translation[name, *params]
286
276
  end
277
+ alias method_missing []
287
278
  end
288
279
  end
@@ -124,16 +124,6 @@ module R18n
124
124
  default
125
125
  end
126
126
 
127
- # Short and pretty way to get translation by method name. If translation
128
- # has name like object methods (+new+, +to_s+, +methods+) use <tt>[]</tt>
129
- # method to access.
130
- #
131
- # Translation can contain variable part. Just set is as <tt>%1</tt>,
132
- # <tt>%2</tt>, etc in translations file and set values as methods params.
133
- def method_missing(name, *params)
134
- self[name, *params]
135
- end
136
-
137
127
  # Return translation with special +name+.
138
128
  #
139
129
  # Translation can contain variable part. Just set is as <tt>%1</tt>,
@@ -153,5 +143,6 @@ module R18n
153
143
  value
154
144
  end
155
145
  end
146
+ alias method_missing []
156
147
  end
157
148
  end
@@ -49,10 +49,10 @@ module R18n
49
49
  def self.deep_merge!(a, b)
50
50
  b.each_pair do |key, value|
51
51
  another = a[key]
52
- if another.nil?
53
- a[key] = value
54
- elsif another.is_a?(Hash) and value.is_a?(Hash)
55
- a[key] = deep_merge!(another, value)
52
+ a[key] = if another.is_a?(Hash) && value.is_a?(Hash)
53
+ deep_merge!(another, value)
54
+ else
55
+ value
56
56
  end
57
57
  end
58
58
  a
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module R18n
3
- VERSION = '0.4.3' unless defined? R18n::VERSION
3
+ VERSION = '0.4.4' unless defined? R18n::VERSION
4
4
  end
@@ -51,8 +51,8 @@ module R18n
51
51
  # Return Hash with translations for +locale+.
52
52
  def load(locale)
53
53
  translations = {}
54
- Dir.glob(File.join(@dir, "**/#{locale.code.downcase}.yml")).each do |i|
55
- Utils.deep_merge!(translations, ::YAML::load_file(i))
54
+ Dir.glob(File.join(@dir, "**/#{locale.code.downcase}.yml")).each do |file_name|
55
+ Utils.deep_merge!(translations, ::YAML::load_file(file_name))
56
56
  end
57
57
  transform(translations)
58
58
  end
@@ -70,11 +70,14 @@ module R18n
70
70
  # Wrap YAML private types to Typed.
71
71
  def transform(a_hash)
72
72
  R18n::Utils.hash_map(a_hash) do |key, value|
73
- [key, case value
74
- when ::YAML::PrivateType then Typed.new(value.type_id, value.value)
75
- when Hash then transform(value)
76
- else value
77
- end]
73
+ [key,
74
+ case value
75
+ when ::YAML::PrivateType
76
+ Typed.new(value.type_id, value.value)
77
+ when Hash
78
+ transform(value)
79
+ else value
80
+ end]
78
81
  end
79
82
  end
80
83
  end
data/locales/th.rb ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module R18n
3
+ class Locales::Th < R18n::Locale
4
+ set :title => 'ภาษาไทย',
5
+
6
+ :wday_names => %w{วันอาทิตย์ วันจันทร์ วันอังคาร วันพุธ วันพฤหัสบดี วันศุกร์ วันวัน วันเสาร์},
7
+ :wday_abbrs => %w{อาทิตย์ จันทร์ อังคาร พุธ พฤหัสบดี ศุกร์ เสาร์},
8
+
9
+ :month_names => %w{มกราคม กุมภาพันธ์ มีนาคม เมษายน พฤษภาคม มิถุนายน กรกฎาคม สิงหาคม กันยายน ตุลาคม พฤศจิกายน},
10
+ :month_abbrs => %w{ม.ค. ก.พ. มี.ค. เม.ย. พ.ค. มิ.ย. ก.ค. ส.ค. ก.ย. ต.ค. พ.ย. ธ.ค.},
11
+
12
+ :date_format => '%d/%m/%Y',
13
+ :full_format => '%e %B',
14
+ :year_format => '_, %Y',
15
+
16
+ :number_decimal => ".",
17
+ :number_group => ","
18
+
19
+ def strftime(time, format)
20
+ year = (time.year + 543).to_s
21
+ super(time, format.gsub('%Y', year).gsub('%y', year[-2..-1]))
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'cs')
3
2
 
4
3
  describe R18n::Locales::Cs do
5
4
  it "should use Czech pluralization" do
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'en-us')
3
2
 
4
3
  describe R18n::Locales::EnUs do
5
4
  it "should format American English date" do
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'en')
3
2
 
4
3
  describe R18n::Locales::En do
5
4
  it "should format English date" do
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'fr')
3
2
 
4
3
  describe R18n::Locales::Fr do
5
4
  it "should format French date" do
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
3
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'it')
4
3
 
5
4
  describe R18n::Locales::It do
6
5
  it "should format Italian date" do
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'pl')
3
2
 
4
3
  describe R18n::Locales::Pl do
5
4
  it "should use Polish pluralization" do
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'ru')
3
2
 
4
3
  describe R18n::Locales::Ru do
5
4
  it "should use Russian pluralization" do
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '..', '..', 'locales', 'sk')
3
2
 
4
3
  describe R18n::Locales::Sk do
5
4
  it "should use Slovak pluralization" do
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe R18n::Locales::Ru do
4
+ it "should use Thai calendar" do
5
+ th = R18n::I18n.new('th')
6
+ th.l(Time.at(0).utc, '%Y %y').should == '2513 13'
7
+ th.l(Time.at(0).utc).should == '01/01/2513 00:00'
8
+ end
9
+ end
data/spec/r18n_spec.rb CHANGED
@@ -2,8 +2,11 @@
2
2
  require File.join(File.dirname(__FILE__), 'spec_helper')
3
3
 
4
4
  describe R18n do
5
+ include R18n::Helpers
6
+
5
7
  after do
6
8
  R18n.default_loader = R18n::Loader::YAML
9
+ R18n.reset
7
10
  end
8
11
 
9
12
  it "should store I18n" do
@@ -11,7 +14,7 @@ describe R18n do
11
14
  R18n.set(i18n)
12
15
  R18n.get.should == i18n
13
16
 
14
- R18n.set(nil)
17
+ R18n.reset
15
18
  R18n.get.should be_nil
16
19
  end
17
20
 
@@ -24,7 +27,35 @@ describe R18n do
24
27
 
25
28
  R18n.get.should == i18n
26
29
  end
30
+
31
+ it "should store I18n via thread_set" do
32
+ i18n = R18n::I18n.new('en')
33
+ R18n.thread_set(i18n)
34
+ R18n.get.should == i18n
35
+
36
+ R18n.reset
37
+ R18n.get.should be_nil
38
+ end
27
39
 
40
+ it "should reset I18n objects and cache" do
41
+ R18n.cache[:a] = 1
42
+ R18n.thread_set(R18n::I18n.new('en'))
43
+
44
+ R18n.reset
45
+ R18n.get.should be_nil
46
+ R18n.cache.should be_empty
47
+ end
48
+
49
+ it "should thread_set setter to I18n" do
50
+ i18n = R18n::I18n.new('en')
51
+ R18n.thread_set(i18n)
52
+
53
+ i18n = R18n::I18n.new('ru')
54
+ R18n.thread_set { i18n }
55
+
56
+ R18n.get.should == i18n
57
+ end
58
+
28
59
  it "should store default loader class" do
29
60
  R18n.default_loader.should == R18n::Loader::YAML
30
61
  R18n.default_loader = Class
@@ -59,8 +90,18 @@ describe R18n do
59
90
 
60
91
  R18n::Utils.deep_merge!(a, b)
61
92
  a.should == { :a => 1,
62
- :b => { :ba => 1, :bb => 1, :bc => 2 },
63
- :c => 1 }
93
+ :b => { :ba => 1, :bb => 2, :bc => 2 },
94
+ :c => 2 }
95
+ end
96
+
97
+ it "should have helpers" do
98
+ obj = R18n::I18n.new 'en'
99
+ R18n.set(obj)
100
+
101
+ r18n.should == obj
102
+ i18n.should == obj
103
+ t.yes.should == 'Yes'
104
+ l(Time.at(0).utc).should == '01/01/1970 00:00'
64
105
  end
65
106
 
66
107
  end
data/spec/spec_helper.rb CHANGED
@@ -5,11 +5,12 @@ require 'pp'
5
5
  dir = Pathname(__FILE__).dirname
6
6
 
7
7
  require dir + '../lib/r18n-core'
8
+ Pathname.glob(dir.join('../locales/*.rb').to_s) { |locale| require locale }
8
9
 
9
- TRANSALTIONS = dir + 'translations'
10
- DIR = TRANSALTIONS + 'general' unless defined? DIR
11
- TWO = TRANSALTIONS + 'two' unless defined? TWO
12
- EXT = R18n::Loader::YAML.new(TRANSALTIONS + 'extension') unless defined? EXT
10
+ TRANSLATIONS = dir + 'translations' unless defined? TRANSLATIONS
11
+ DIR = TRANSLATIONS + 'general' unless defined? DIR
12
+ TWO = TRANSLATIONS + 'two' unless defined? TWO
13
+ EXT = R18n::Loader::YAML.new(TRANSLATIONS + 'extension') unless defined? EXT
13
14
 
14
15
  Spec::Runner.configure do |config|
15
16
  config.before { R18n.cache.clear }
@@ -0,0 +1 @@
1
+ deep: Deep one
@@ -1,2 +1,3 @@
1
1
  one: No one
2
2
  ext: Extension
3
+ deep: "no"
@@ -32,7 +32,7 @@ describe R18n::Loader::YAML do
32
32
  end
33
33
 
34
34
  it "should load in dir recursively" do
35
- loader = R18n::Loader::YAML.new(TRANSALTIONS)
35
+ loader = R18n::Loader::YAML.new(TRANSLATIONS)
36
36
  loader.available.should =~ [R18n::Locale.load('ru'),
37
37
  R18n::Locale.load('en'),
38
38
  R18n::Locale.load('fr'),
@@ -40,9 +40,10 @@ describe R18n::Loader::YAML do
40
40
  R18n::Locale.load('no-lc')]
41
41
 
42
42
  translation = loader.load(R18n::Locale.load('en'))
43
- translation['one'].should == 'One'
43
+ translation['two'].should == 'Two'
44
44
  translation['in']['two'].should == 'Two'
45
45
  translation['ext'].should == 'Extension'
46
+ translation['deep'].should == 'Deep one'
46
47
  end
47
48
 
48
49
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r18n-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey "A.I." Sitnik
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-26 00:00:00 +03:00
12
+ date: 2010-03-29 00:00:00 +04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -35,6 +35,7 @@ files:
35
35
  - base/pt_br.yml
36
36
  - base/es.yml
37
37
  - base/fr.yml
38
+ - base/th.yml
38
39
  - base/en.yml
39
40
  - base/zh.yml
40
41
  - lib/r18n-core.rb
@@ -49,6 +50,7 @@ files:
49
50
  - lib/r18n-core/unsupported_locale.rb
50
51
  - lib/r18n-core/locale.rb
51
52
  - lib/r18n-core/i18n.rb
53
+ - lib/r18n-core/helpers.rb
52
54
  - locales/it.rb
53
55
  - locales/pl.rb
54
56
  - locales/en.rb
@@ -57,6 +59,7 @@ files:
57
59
  - locales/kk.rb
58
60
  - locales/en-us.rb
59
61
  - locales/zh.rb
62
+ - locales/th.rb
60
63
  - locales/fr.rb
61
64
  - locales/ru.rb
62
65
  - locales/sk.rb
@@ -97,6 +100,7 @@ summary: I18n tool to translate your Ruby application.
97
100
  test_files:
98
101
  - spec/translated_spec.rb
99
102
  - spec/locales/it_spec.rb
103
+ - spec/locales/th_spec.rb
100
104
  - spec/locales/fr_spec.rb
101
105
  - spec/locales/sk_spec.rb
102
106
  - spec/locales/pl_spec.rb
@@ -115,6 +119,7 @@ test_files:
115
119
  - spec/translations/two/en.yml
116
120
  - spec/translations/extension/no-tr.yml
117
121
  - spec/translations/extension/en.yml
122
+ - spec/translations/extension/deep/en.yml
118
123
  - spec/filters_spec.rb
119
124
  - spec/i18n_spec.rb
120
125
  - spec/locale_spec.rb