localite 0.3 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Manifest +44 -0
  2. data/VERSION +1 -1
  3. data/bin/list-tr +10 -0
  4. data/lib/localite.rb +161 -43
  5. data/lib/localite/filter.rb +23 -64
  6. data/lib/localite/format.rb +36 -0
  7. data/lib/localite/node_filter.rb +197 -0
  8. data/lib/localite/scopes.rb +93 -0
  9. data/lib/localite/settings.rb +139 -17
  10. data/lib/localite/storage.rb +132 -0
  11. data/lib/localite/template.rb +29 -25
  12. data/lib/localite/tr.rb +292 -0
  13. data/lib/localite/translate.rb +46 -20
  14. data/localite.gemspec +9 -6
  15. data/localite.tmproj +3 -99
  16. data/tasks/echoe.rake +1 -1
  17. data/test/i18n/de.tr +5 -0
  18. data/test/i18n/en.tr +16 -0
  19. data/test/rails/Rakefile +10 -0
  20. data/test/rails/app/controllers/application_controller.rb +10 -0
  21. data/test/rails/app/controllers/localite_controller.rb +20 -0
  22. data/test/rails/app/views/localite/index.html.erb +19 -0
  23. data/test/rails/app/views/localite/template.de.html.erb +1 -0
  24. data/test/rails/app/views/localite/template.en.html.erb +1 -0
  25. data/test/rails/config/boot.rb +110 -0
  26. data/test/rails/config/environment.rb +50 -0
  27. data/test/rails/config/environments/development.rb +17 -0
  28. data/test/rails/config/environments/production.rb +28 -0
  29. data/test/rails/config/environments/test.rb +28 -0
  30. data/test/rails/config/initializers/new_rails_defaults.rb +21 -0
  31. data/test/rails/config/initializers/session_store.rb +15 -0
  32. data/test/rails/config/locales/de.yml +4 -0
  33. data/test/rails/config/locales/en.yml +4 -0
  34. data/test/rails/config/routes.rb +13 -0
  35. data/test/rails/script/console +3 -0
  36. data/test/rails/script/server +3 -0
  37. data/test/rails/test/functional/localite_controller_test.rb +56 -0
  38. data/test/rails/test/test_helper.rb +38 -0
  39. data/test/test.rb +4 -1
  40. metadata +51 -11
  41. data/lib/localite/scope.rb +0 -140
  42. data/test/i18n/de.yml +0 -15
data/Manifest CHANGED
@@ -0,0 +1,44 @@
1
+ Manifest
2
+ Rakefile
3
+ VERSION
4
+ bin/list-tr
5
+ config/dependencies.rb
6
+ config/gem.yml
7
+ lib/localite.rb
8
+ lib/localite/filter.rb
9
+ lib/localite/format.rb
10
+ lib/localite/node_filter.rb
11
+ lib/localite/scopes.rb
12
+ lib/localite/settings.rb
13
+ lib/localite/storage.rb
14
+ lib/localite/template.rb
15
+ lib/localite/tr.rb
16
+ lib/localite/translate.rb
17
+ localite.tmproj
18
+ script/console
19
+ script/rebuild
20
+ tasks/echoe.rake
21
+ test/i18n/de.tr
22
+ test/i18n/en.tr
23
+ test/initializers/fake_rails.rb
24
+ test/rails/Rakefile
25
+ test/rails/app/controllers/application_controller.rb
26
+ test/rails/app/controllers/localite_controller.rb
27
+ test/rails/app/views/localite/index.html.erb
28
+ test/rails/app/views/localite/template.de.html.erb
29
+ test/rails/app/views/localite/template.en.html.erb
30
+ test/rails/config/boot.rb
31
+ test/rails/config/environment.rb
32
+ test/rails/config/environments/development.rb
33
+ test/rails/config/environments/production.rb
34
+ test/rails/config/environments/test.rb
35
+ test/rails/config/initializers/new_rails_defaults.rb
36
+ test/rails/config/initializers/session_store.rb
37
+ test/rails/config/locales/de.yml
38
+ test/rails/config/locales/en.yml
39
+ test/rails/config/routes.rb
40
+ test/rails/script/console
41
+ test/rails/script/server
42
+ test/rails/test/functional/localite_controller_test.rb
43
+ test/rails/test/test_helper.rb
44
+ test/test.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3
1
+ 0.5.6
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "#{File.dirname(__FILE__)}/../lib/localite"
4
+ require "pp"
5
+ ARGV.each do |file|
6
+ keys = Localite::Backend::Tr.new(File.new(file)).keys
7
+ keys.each do |key|
8
+ puts key
9
+ end
10
+ end
@@ -10,35 +10,34 @@ module Localite; end
10
10
 
11
11
  file_dir = File.expand_path(File.dirname(__FILE__))
12
12
 
13
- require "#{file_dir}/localite/scope"
14
- require "#{file_dir}/localite/settings"
15
- require "#{file_dir}/localite/translate"
16
- require "#{file_dir}/localite/template"
13
+ $: << file_dir
14
+ require "localite/format"
15
+ require "localite/scopes"
16
+ require "localite/settings"
17
+ require "localite/translate"
18
+ require "localite/template"
19
+ require "localite/storage"
17
20
 
18
21
  module Localite
19
22
  #
20
23
  # a logger
21
24
  def self.logger
25
+ return @logger if @logger
26
+
22
27
  klass = defined?(ActiveSupport) ? ActiveSupport::BufferedLogger : Logger
23
28
 
24
- @logger ||= begin
29
+ @logger = begin
25
30
  klass.new("log/localite.log")
26
31
  rescue Errno::ENOENT
27
32
  ::Logger.new(STDERR)
28
33
  end
34
+
35
+ @logger.warn "=== Initialize localite logging: #{Time.now}"
36
+ @logger
29
37
  end
30
38
 
31
39
  extend Settings
32
40
  extend Translate
33
- extend Scope
34
-
35
- private
36
-
37
- def self.template(template, *args)
38
- Template.run mode, template, *args
39
- end
40
-
41
- public
42
41
 
43
42
  #
44
43
  # Translating a string:
@@ -49,7 +48,12 @@ module Localite
49
48
  module StringAdapter
50
49
  def t(*args)
51
50
  translated = Localite.translate(self, :no_raise) || self
52
- Localite.template translated, *args
51
+ Localite::Template.run translated, *args
52
+ end
53
+
54
+ def t?(*args)
55
+ translated = Localite.translate(self, :no_raise)
56
+ Localite::Template.run translated, *args if translated
53
57
  end
54
58
  end
55
59
 
@@ -62,13 +66,13 @@ module Localite
62
66
  module SymbolAdapter
63
67
  def t(*args)
64
68
  translated = Localite.translate(self, :do_raise)
65
- Localite.template translated, *args
69
+ Localite::Template.run translated, *args
66
70
  end
67
71
 
68
72
  # returns nil, if there is no translation.
69
73
  def t?(*args)
70
74
  translated = Localite.translate(self, :no_raise)
71
- Localite.template translated, *args if translated
75
+ Localite::Template.run translated, *args if translated
72
76
  end
73
77
  end
74
78
 
@@ -91,51 +95,51 @@ module Localite::Etest
91
95
  assert !I18n.load_path.empty?
92
96
 
93
97
  assert_equal("en.t", "t".t)
94
- Localite.in("en") {
98
+ Localite.locale("en") {
95
99
  assert_equal("en.t", "t".t )
96
100
  }
97
101
 
98
- Localite.in("de") {
102
+ Localite.locale("de") {
99
103
  assert_equal("de.t", "t".t )
100
104
  }
101
105
 
102
- assert_equal("de.t", Localite.in("de") { "t".t })
106
+ assert_equal("de.t", Localite.locale("de") { "t".t })
103
107
  end
104
108
 
105
109
  def test_lookup_de
106
- Localite.in("de") do
110
+ Localite.locale("de") do
107
111
  # flat translation
108
112
  assert_equal "de.t", "t".t
109
113
 
110
114
  Localite.scope(:outer, :inner) do
111
115
  assert_equal("de/outer/inner/x1", "x1".t)
112
116
  end
113
-
117
+
114
118
  # Miss "x1", and don't translate missing entries
115
119
  assert_equal("x1", "x1".t)
116
120
  end
117
121
  end
118
122
 
119
123
  def test_lookup_in_base
120
- Localite.in("en") do
124
+ Localite.locale("en") do
121
125
  # lookup "base" in base translation
122
126
  assert_equal "en_only", "base".t
123
127
  end
124
128
 
125
- Localite.in("de") do
129
+ Localite.locale("de") do
126
130
  # lookup "base" in base (i.e. en) translation
127
131
  assert_equal "en_only", "base".t
128
132
  end
129
133
  end
130
134
 
131
135
  def test_lookup_en
132
- Localite.in("en") do
136
+ Localite.locale("en") do
133
137
 
134
138
  # flat translation
135
139
  assert_equal "en.t", "t".t
136
140
 
137
- Localite.scope(:outer, :inner, :x1) do
138
- assert_equal("en/outer/inner/x1", "x1".t)
141
+ Localite.scope(:outer, :inner) do
142
+ assert_equal("en/outer/inner/x1", :x1.t)
139
143
  end
140
144
 
141
145
  # Miss "x1", and don't translate missing entries
@@ -160,11 +164,11 @@ module Localite::Etest
160
164
 
161
165
  assert_equal "en_only", :base.t
162
166
 
163
- Localite.in("en") do
167
+ Localite.locale("en") do
164
168
  assert_equal "en_only", :base.t
165
169
  end
166
170
 
167
- Localite.in("de") do
171
+ Localite.locale("de") do
168
172
  assert_equal "en_only", :base.t
169
173
  end
170
174
  end
@@ -175,13 +179,13 @@ module Localite::Etest
175
179
  assert_equal "en_only", :missing.t
176
180
  }
177
181
 
178
- Localite.in("en") do
182
+ Localite.locale("en") do
179
183
  assert_raise(Localite::Translate::Missing) {
180
184
  :missing.t
181
185
  }
182
186
  end
183
187
 
184
- Localite.in("de") do
188
+ Localite.locale("de") do
185
189
  assert_raise(Localite::Translate::Missing) {
186
190
  :missing.t
187
191
  }
@@ -193,16 +197,130 @@ module Localite::Etest
193
197
  assert_kind_of(String, $!.to_s)
194
198
  end
195
199
  end
196
-
197
- # def test_html
198
- # assert_equal ">", "{*'>'*}".t(:xyz => [1, 2, 3], :fl => [1.0])
199
- # assert_equal "&gt;", "{*'>'*}".t(:html, :xyz => [1, 2, 3], :fl => [1.0])
200
- # assert_equal "3 Fixnums > 1 Float", "{*pl xyz*} > {*pl fl*}".t(:xyz => [1, 2, 3], :fl => [1.0])
201
- # assert_equal "3 Fixnums &gt; 1 Float", "{*pl xyz*} > {*pl fl*}".t(:html, :xyz => [1, 2, 3], :fl => [1.0])
202
- # end
203
- #
204
- # def test_tmpl
205
- # # assert_equal "3 chars", "{*len*} chars".t(:len => 3)
206
- # assert_equal "3 chars", "{*length*} chars".t(:length => 3)
207
- # end
200
+
201
+ def catch_exception(klass, &block)
202
+ yield
203
+ nil
204
+ rescue klass
205
+ $!
206
+ end
207
+
208
+ def test_missing_translation_wo_scope
209
+ r = catch_exception(Localite::Translate::Missing) do
210
+ Localite.scope(:locale => :de, :format => :text) do
211
+ :x.t
212
+ end
213
+ end
214
+
215
+ assert_equal(:de, r.locale)
216
+ assert_equal(:x, r.string)
217
+ assert_equal("", r.scope)
218
+
219
+ r = catch_exception(Localite::Translate::Missing) do
220
+ Localite.scope(:locale => :de, :format => :html) do
221
+ :x.t
222
+ end
223
+ end
224
+
225
+ assert_equal(:de, r.locale)
226
+ assert_equal(:x, r.string)
227
+ assert_equal("", r.scope)
228
+
229
+ r = catch_exception(Localite::Translate::Missing) do
230
+ Localite.scope(:locale => :de) do
231
+ :x.t
232
+ end
233
+ end
234
+
235
+ assert_equal(:de, r.locale)
236
+ assert_equal(:x, r.string)
237
+ assert_equal("", r.scope)
238
+ end
239
+
240
+ def test_missing_translation_w_scope
241
+ r = catch_exception(Localite::Translate::Missing) do
242
+ Localite.locale(:de) do
243
+ Localite.scope(:ab, :cd) do
244
+ :yx.t
245
+ end
246
+ end
247
+ end
248
+
249
+ assert_equal(:de, r.locale)
250
+ assert_equal(:yx, r.string)
251
+ assert_equal("ab:cd", r.scope)
252
+ end
253
+
254
+ def test_reset_scope
255
+ r = catch_exception(Localite::Translate::Missing) do
256
+ Localite.scope(:ab) do
257
+ Localite.scope(:cd) do
258
+ :yx.t
259
+ end
260
+ end
261
+ end
262
+
263
+ assert_equal("ab:cd", r.scope)
264
+
265
+ r = catch_exception(Localite::Translate::Missing) do
266
+ Localite.scope(:ab) do
267
+ Localite.scope!(:cd) do
268
+ assert_equal([:cd], Localite.current_scope)
269
+ end
270
+ assert_equal([:ab], Localite.current_scope)
271
+
272
+ Localite.scope!(:cd) do
273
+ :yx.t
274
+ end
275
+ end
276
+ end
277
+
278
+ assert_equal("cd", r.scope)
279
+ end
280
+
281
+ def test_default_format
282
+ assert_equal "abc", "param".t(:xxx => "abc")
283
+ assert_equal "a > c", "param".t(:xxx => "a > c")
284
+ assert_equal "abc", "param".t(:xxx => "abc")
285
+ end
286
+
287
+ def test_text_format
288
+ assert_equal "a > c", Localite.format(:text) { "param".t(:xxx => "a > c") }
289
+ end
290
+
291
+ def test_html_format
292
+ Localite.format(:html) {
293
+ assert_equal(:html, Localite.current_format)
294
+ assert_equal "a &gt; c", "param".t(:xxx => "a > c")
295
+ }
296
+
297
+ assert_equal "a &gt; c", Localite.format(:html) { "param".t(:xxx => "a > c") }
298
+ end
299
+
300
+ def test_format_scope
301
+ Localite.format(:html) do
302
+ assert_equal :html, Localite.current_format
303
+ assert_equal("This is hypertext", :title.t)
304
+ assert_equal("This is &lt;&gt; hypertext", :title2.t)
305
+ end
306
+ Localite.format(:text) do
307
+ assert_equal :text, Localite.current_format
308
+ assert_equal("This is hypertext", :title.t)
309
+ assert_equal("This is <> hypertext", :title2.t)
310
+ end
311
+ end
312
+
313
+ def test_unavailable
314
+ Localite.locale("unknown") do
315
+ assert_equal(:en, Localite.current_locale)
316
+ assert_equal("This is hypertext", :title.t)
317
+ end
318
+ end
319
+
320
+ def test_inspect
321
+ assert_nothing_raised {
322
+ Localite.inspect
323
+ }
324
+ end
208
325
  end
326
+
@@ -1,78 +1,24 @@
1
1
  module Localite::Filter
2
2
  module ControllerFilter
3
- def self.locale(controller)
4
- #
5
- # get the current locale
6
- locale = begin
7
- controller.send(:current_locale)
8
- rescue NoMethodError
9
- end
10
- end
11
-
3
+ #
4
+ # set up localite for this action.
12
5
  def self.filter(controller, &block)
13
- #
14
- # set up localite for this action.
15
- Localite.in(locale(controller)) do
16
- Localite.html(&block)
6
+ args = controller.send(:localite_scopes)
7
+ args.push :locale => controller.send(:current_locale),
8
+ :format => controller.send(:localite_format)
17
9
 
18
- filter_response controller
10
+ Localite.scope(*args) do
11
+ if controller.logger && Rails.env.development?
12
+ controller.logger.warn "localite: [#{Localite.current_locale}]"
13
+ end
14
+ yield
19
15
  end
20
16
  rescue
21
17
  if Rails.env.development?
22
18
  controller.response.body = "Caught exception: " + CGI::escapeHTML($!.inspect)
23
- STDERR.puts $!.to_s + "\n\t" + $!.backtrace.join("\n\t")
24
19
  end
25
20
  raise
26
21
  end
27
-
28
- def self.filter_response(controller)
29
- return unless controller.response.headers["Content-Type"] =~ /text\/html/
30
- controller.response.body = filter_lang_nodes(controller.response.body)
31
- end
32
-
33
- def self.filter_lang_nodes(body)
34
- doc = Nokogiri.XML "<filter-outer-span xmlns:fb='http://facebook.com/'>#{body}</filter-outer-span>"
35
-
36
- doc.css("[lang]").each do |node|
37
- if Localite.locale.to_s != node["lang"]
38
- node.remove
39
- next
40
- end
41
-
42
- #
43
- # we have a node with content specific for the current locale,
44
- # i.e. a node to keep. If we find a base locale sibling (i.e.
45
- # with identical attributes but no "lang" attribute) prior
46
- # this node we have to remove that.
47
- next unless base = base_node(node)
48
- base.remove
49
- end
50
-
51
- doc.css("filter-outer-span").inner_html
52
- end
53
-
54
- def self.base_node(node)
55
- previous = node
56
- while (previous = previous.previous) && previous.name == "text" do
57
- :void
58
- end
59
-
60
- return previous if base_node?(node, previous)
61
- end
62
-
63
- def self.base_node?(me, other_node)
64
- return false if !other_node
65
- return false if me.name != other_node.name
66
- return false if other_node.attributes.key?("lang")
67
- return false if me.attributes.length != other_node.attributes.length + 1
68
-
69
- # do we have a mismatching attribute?
70
- other_node.attributes.each { |k,v|
71
- return false if me.attributes[k] != v
72
- }
73
-
74
- true
75
- end
76
22
  end
77
23
 
78
24
  module ControllerMethods
@@ -82,10 +28,23 @@ module Localite::Filter
82
28
  return params[:locale] if params[:locale] && params[:locale] =~ /^[a-z][a-z]$/
83
29
  return params[:lang] if params[:lang] && params[:lang] =~ /^[a-z][a-z]$/
84
30
  end
31
+
32
+ #
33
+ # return the current scope(s) as an array.
34
+ def localite_scopes
35
+ []
36
+ end
37
+
38
+ #
39
+ # return the current scope(s) as an array.
40
+ def localite_format
41
+ :html
42
+ end
85
43
  end
86
44
 
87
45
  def self.included(klass)
88
46
  klass.send :include, ControllerMethods
47
+ klass.send :helper_method, :current_locale
89
48
  klass.send :around_filter, ControllerFilter
90
49
  end
91
50
  end