localite 0.3 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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