r18n-core 0.4.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -1
- data/ChangeLog +21 -0
- data/LICENSE +2 -2
- data/README.md +456 -0
- data/Rakefile +2 -1
- data/base/gl.yml +31 -0
- data/base/it.yml +1 -1
- data/lib/r18n-core/filter_list.rb +157 -0
- data/lib/r18n-core/filters.rb +40 -36
- data/lib/r18n-core/i18n.rb +17 -9
- data/lib/r18n-core/locale.rb +5 -2
- data/lib/r18n-core/translated.rb +18 -15
- data/lib/r18n-core/translated_string.rb +14 -0
- data/lib/r18n-core/translation.rb +19 -20
- data/lib/r18n-core/untranslated.rb +8 -5
- data/lib/r18n-core/utils.rb +5 -1
- data/lib/r18n-core/version.rb +1 -1
- data/lib/r18n-core/yaml_loader.rb +2 -2
- data/lib/r18n-core.rb +60 -13
- data/locales/ca.rb +1 -0
- data/locales/cs.rb +0 -1
- data/locales/en-au.rb +0 -1
- data/locales/en-gb.rb +0 -1
- data/locales/en-us.rb +0 -1
- data/locales/en.rb +1 -1
- data/locales/fr.rb +1 -1
- data/locales/gl.rb +21 -0
- data/locales/hu.rb +1 -2
- data/locales/nb-no.rb +2 -3
- data/locales/nl.rb +4 -2
- data/locales/pt-br.rb +0 -1
- data/locales/pt.rb +0 -1
- data/locales/sv-se.rb +2 -3
- data/locales/th.rb +1 -1
- data/locales/tr.rb +2 -4
- data/locales/zh-cn.rb +7 -0
- data/locales/zh-tw.rb +7 -0
- data/r18n-core.gemspec +10 -10
- data/spec/filters_spec.rb +38 -7
- data/spec/i18n_spec.rb +15 -18
- data/spec/locale_spec.rb +19 -14
- data/spec/locales/cs_spec.rb +1 -1
- data/spec/locales/pl_spec.rb +1 -1
- data/spec/locales/ru_spec.rb +1 -1
- data/spec/locales/sk_spec.rb +1 -1
- data/spec/r18n_spec.rb +64 -22
- data/spec/spec_helper.rb +2 -3
- data/spec/translated_spec.rb +18 -4
- data/spec/translation_spec.rb +17 -6
- data/spec/translations/general/en.yml +1 -0
- data/spec/yaml_loader_spec.rb +10 -10
- metadata +163 -141
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -35
- data/README.rdoc +0 -482
- data/spec/translations/empty/en.yml +0 -0
data/lib/r18n-core/filters.rb
CHANGED
@@ -41,7 +41,7 @@ module R18n
|
|
41
41
|
# end
|
42
42
|
#
|
43
43
|
# i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"
|
44
|
-
#
|
44
|
+
#
|
45
45
|
# Use String class as type to add global filter for all translated strings:
|
46
46
|
#
|
47
47
|
# R18n::Filters.add(String, :escape_html) do |content, config, params|
|
@@ -73,6 +73,11 @@ module R18n
|
|
73
73
|
# R18n::Filters.on(:no_space)
|
74
74
|
# i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"
|
75
75
|
# R18n::Filters.delete(:no_space)
|
76
|
+
#
|
77
|
+
# You can enabled/disabled filters only for special I18n object:
|
78
|
+
#
|
79
|
+
# R18n::I18n.new('en', nil, :on_filters => [:untranslated_html, :no_space],
|
80
|
+
# :off_filters => :untranslated )
|
76
81
|
module Filters
|
77
82
|
class << self
|
78
83
|
# Hash of filter names to Filters.
|
@@ -90,33 +95,6 @@ module R18n
|
|
90
95
|
# Hash of types to enabled passive and active filters.
|
91
96
|
attr_accessor :enabled
|
92
97
|
|
93
|
-
# Process +value+ by filters in +enabled+.
|
94
|
-
def process(enabled, type, value, locale, path, params)
|
95
|
-
config = { :locale => locale, :path => path }
|
96
|
-
|
97
|
-
enabled[type].each do |filter|
|
98
|
-
value = filter.call(value, config, *params)
|
99
|
-
end
|
100
|
-
|
101
|
-
if value.is_a? String
|
102
|
-
value = TranslatedString.new(value, locale, path)
|
103
|
-
process_string(enabled, value, config, params)
|
104
|
-
else
|
105
|
-
value
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Process +value+ by global filters in +enabled+.
|
110
|
-
def process_string(enabled, value, config, params)
|
111
|
-
if config.is_a? String
|
112
|
-
config = { :locale => value.locale, :path => config }
|
113
|
-
end
|
114
|
-
enabled[String].each do |f|
|
115
|
-
value = f.call(value, config, *params)
|
116
|
-
end
|
117
|
-
value
|
118
|
-
end
|
119
|
-
|
120
98
|
# Rebuild +active_enabled+ and +passive_enabled+ for +type+.
|
121
99
|
def rebuild_enabled!(type)
|
122
100
|
@passive_enabled[type] = []
|
@@ -138,10 +116,10 @@ module R18n
|
|
138
116
|
# Add new filter for +type+ with +name+ and return filter object. You
|
139
117
|
# can use String class as +type+ to add global filter for all translated
|
140
118
|
# string.
|
141
|
-
#
|
119
|
+
#
|
142
120
|
# Filter content will be sent to +block+ as first argument, struct with
|
143
121
|
# config as second and filters parameters will be in next arguments.
|
144
|
-
#
|
122
|
+
#
|
145
123
|
# Options:
|
146
124
|
# * +position+ – change order on processing several filters for same type.
|
147
125
|
# Note that passive filters will be always run before active.
|
@@ -174,6 +152,7 @@ module R18n
|
|
174
152
|
rebuild_enabled! type
|
175
153
|
end
|
176
154
|
|
155
|
+
@new_filter_listener.call(filter) if @new_filter_listener
|
177
156
|
filter
|
178
157
|
end
|
179
158
|
|
@@ -206,6 +185,15 @@ module R18n
|
|
206
185
|
filter.enabled = true
|
207
186
|
filter.types.each { |type| rebuild_enabled! type }
|
208
187
|
end
|
188
|
+
|
189
|
+
# Return filters, which be added inside +block+.
|
190
|
+
def listen(&block)
|
191
|
+
filters = []
|
192
|
+
@new_filter_listener = proc { |i| filters << i }
|
193
|
+
yield
|
194
|
+
@new_filter_listener = nil
|
195
|
+
filters
|
196
|
+
end
|
209
197
|
end
|
210
198
|
|
211
199
|
Filters.defined = {}
|
@@ -239,7 +227,11 @@ module R18n
|
|
239
227
|
Filters.add(String, :variables) do |content, config, *params|
|
240
228
|
content = content.clone
|
241
229
|
params.each_with_index do |param, i|
|
242
|
-
|
230
|
+
param = config[:locale].localize(param)
|
231
|
+
if defined? ActiveSupport::SafeBuffer
|
232
|
+
param = ActiveSupport::SafeBuffer.new + param
|
233
|
+
end
|
234
|
+
content.gsub! "%#{i+1}", param
|
243
235
|
end
|
244
236
|
content
|
245
237
|
end
|
@@ -248,9 +240,21 @@ module R18n
|
|
248
240
|
"#{translated}[#{untranslated}]"
|
249
241
|
end
|
250
242
|
|
243
|
+
Filters.add(Untranslated, :untranslated_bash) do |v, c, transl, untransl|
|
244
|
+
"#{transl}\e[0;31m[#{untransl}]\e[0m"
|
245
|
+
end
|
246
|
+
Filters.off(:untranslated_bash)
|
247
|
+
|
251
248
|
Filters.add(Untranslated, :untranslated_html) do |v, c, transl, untransl|
|
252
|
-
|
253
|
-
|
249
|
+
if defined? ActiveSupport::SafeBuffer
|
250
|
+
transl <<
|
251
|
+
'<span style="color: red">['.html_safe <<
|
252
|
+
untransl <<
|
253
|
+
']</span>'.html_safe
|
254
|
+
else
|
255
|
+
Utils.escape_html(transl) <<
|
256
|
+
'<span style="color: red">[' << Utils.escape_html(untransl) << ']</span>'
|
257
|
+
end
|
254
258
|
end
|
255
259
|
Filters.off(:untranslated_html)
|
256
260
|
|
@@ -275,9 +279,9 @@ module R18n
|
|
275
279
|
end
|
276
280
|
Filters.off(:global_escape_html)
|
277
281
|
|
278
|
-
Filters.add('markdown', :
|
279
|
-
require '
|
280
|
-
::
|
282
|
+
Filters.add('markdown', :kramdown, :passive => true) do |content, config|
|
283
|
+
require 'kramdown'
|
284
|
+
::Kramdown::Document.new(content).to_html
|
281
285
|
end
|
282
286
|
|
283
287
|
Filters.add('textile', :redcloth, :passive => true) do |content, config|
|
data/lib/r18n-core/i18n.rb
CHANGED
@@ -114,11 +114,6 @@ module R18n
|
|
114
114
|
locales.map! { |i| i[0] }
|
115
115
|
end
|
116
116
|
|
117
|
-
# Return Array of locales with available translations.
|
118
|
-
def self.available_locales(places)
|
119
|
-
convert_places(places).map { |i| i.available }.flatten.uniq
|
120
|
-
end
|
121
|
-
|
122
117
|
# Load default loader for elements in +places+ with only constructor
|
123
118
|
# argument.
|
124
119
|
def self.convert_places(places)
|
@@ -147,7 +142,7 @@ module R18n
|
|
147
142
|
#
|
148
143
|
# +Locales+ must be a locale code (RFC 3066) or array, ordered by priority.
|
149
144
|
# +Translation_places+ must be a string with path or array.
|
150
|
-
def initialize(locales, translation_places = nil)
|
145
|
+
def initialize(locales, translation_places = nil, opts = {})
|
151
146
|
locales = Array(locales)
|
152
147
|
|
153
148
|
if not locales.empty? and Locale.exists? locales.first
|
@@ -172,6 +167,12 @@ module R18n
|
|
172
167
|
|
173
168
|
@translation_places = self.class.convert_places(@original_places)
|
174
169
|
|
170
|
+
if opts[:on_filters] or opts[:off_filters]
|
171
|
+
@filters = CustomFilterList.new(opts[:on_filters], opts[:off_filters])
|
172
|
+
else
|
173
|
+
@filters = GlobalFilterList.instance
|
174
|
+
end
|
175
|
+
|
175
176
|
key = translation_cache_key
|
176
177
|
if R18n.cache.has_key? key
|
177
178
|
@locale, @translation = *R18n.cache[key]
|
@@ -180,13 +181,20 @@ module R18n
|
|
180
181
|
end
|
181
182
|
end
|
182
183
|
|
184
|
+
# Return custom filters list
|
185
|
+
def filter_list
|
186
|
+
@filters
|
187
|
+
end
|
188
|
+
|
183
189
|
# Return unique key for current locales in translation and places.
|
184
190
|
def translation_cache_key
|
185
191
|
@available_codes ||= @translation_places.inject([]) { |all, i|
|
186
192
|
all + i.available }.uniq.map { |i| i.code.downcase }
|
187
193
|
(@locales_codes & @available_codes).join(',') + '@' +
|
194
|
+
@filters.hash.to_s +
|
188
195
|
R18n.default_loader.hash.to_s +
|
189
|
-
@translation_places.hash.to_s +
|
196
|
+
@translation_places.hash.to_s +
|
197
|
+
R18n.extension_places.hash.to_s
|
190
198
|
end
|
191
199
|
|
192
200
|
# Reload translations.
|
@@ -218,7 +226,7 @@ module R18n
|
|
218
226
|
end
|
219
227
|
end
|
220
228
|
|
221
|
-
@translation = Translation.new @
|
229
|
+
@translation = Translation.new(@locale, '', :filters => @filters)
|
222
230
|
@locales.each do |locale|
|
223
231
|
loaded = false
|
224
232
|
available_in_places.each do |place, available|
|
@@ -241,7 +249,7 @@ module R18n
|
|
241
249
|
|
242
250
|
# Return Array of locales with available translations.
|
243
251
|
def available_locales
|
244
|
-
@available ||=
|
252
|
+
@available ||= R18n.available_locales(@translation_places)
|
245
253
|
end
|
246
254
|
|
247
255
|
# Convert +object+ to String, according to the rules of the current locale.
|
data/lib/r18n-core/locale.rb
CHANGED
@@ -38,7 +38,7 @@ module R18n
|
|
38
38
|
#
|
39
39
|
# Get Russian locale and print it information
|
40
40
|
#
|
41
|
-
# ru = R18n
|
41
|
+
# ru = R18n.locale('ru')
|
42
42
|
# ru.title #=> "Русский"
|
43
43
|
# ru.code #=> "ru"
|
44
44
|
# ru.ltr? #=> true
|
@@ -106,7 +106,9 @@ module R18n
|
|
106
106
|
|
107
107
|
# Locale RFC 3066 code.
|
108
108
|
def code
|
109
|
-
self.class.name.split('::').last
|
109
|
+
name = self.class.name.split('::').last
|
110
|
+
lang, culture = name.match(/([A-Z][a-z]+)([A-Z]\w+)?/).captures
|
111
|
+
lang.downcase + (culture ? '-' + culture.upcase : '')
|
110
112
|
end
|
111
113
|
|
112
114
|
set :sublocales => %w{en},
|
@@ -119,6 +121,7 @@ module R18n
|
|
119
121
|
|
120
122
|
def month_standalone; month_names; end
|
121
123
|
def month_abbrs; month_names; end
|
124
|
+
def wday_abbrs; wday_names; end
|
122
125
|
|
123
126
|
# Is locale has left-to-right write direction.
|
124
127
|
def ltr?; true; end
|
data/lib/r18n-core/translated.rb
CHANGED
@@ -27,8 +27,6 @@ module R18n
|
|
27
27
|
# proxy-method +title+, which will use +title_ru+ for Russian users and
|
28
28
|
# +title_en+ for English:
|
29
29
|
#
|
30
|
-
# require 'r18n-core/translated'
|
31
|
-
#
|
32
30
|
# class Product
|
33
31
|
# include DataMapper::Resource
|
34
32
|
# property :title_ru, String
|
@@ -61,10 +59,9 @@ module R18n
|
|
61
59
|
# Proxy-method support all funtion from I18n: global and type filters,
|
62
60
|
# pluralization, variables. It also return TranslatedString or Untranslated.
|
63
61
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
# must call <tt>i18n</tt> helper in Sinatra before use models.
|
62
|
+
# By default it use <tt>R18n.get</tt> to get I18n object (so, you must set it
|
63
|
+
# before use model), but you can overwrite object +r18n+ method to change
|
64
|
+
# default logic.
|
68
65
|
#
|
69
66
|
# See R18n::Translated::Base for class method documentation.
|
70
67
|
#
|
@@ -89,6 +86,12 @@ module R18n
|
|
89
86
|
end
|
90
87
|
end
|
91
88
|
|
89
|
+
# Access to I18n object. By default return global I18n object from
|
90
|
+
# <tt>R18n.get</tt>.
|
91
|
+
def r18n
|
92
|
+
R18n.get
|
93
|
+
end
|
94
|
+
|
92
95
|
# Module with class methods, which be added after R18n::Translated include.
|
93
96
|
module Base
|
94
97
|
# Hash of translation method names to it type for filters.
|
@@ -96,7 +99,7 @@ module R18n
|
|
96
99
|
|
97
100
|
# Add several proxy +methods+. See R18n::Translated for description.
|
98
101
|
# It’s more compact, that +translation+.
|
99
|
-
#
|
102
|
+
#
|
100
103
|
# translations :title, :keywords, [:desciption, {:type => 'markdown'}]
|
101
104
|
def translations(*methods)
|
102
105
|
methods.each do |method|
|
@@ -106,7 +109,7 @@ module R18n
|
|
106
109
|
|
107
110
|
# Add proxy-method +name+. See R18n::Translated for description.
|
108
111
|
# It’s more useful to set options.
|
109
|
-
#
|
112
|
+
#
|
110
113
|
# translation :desciption, :type => 'markdown'
|
111
114
|
def translation(name, options = {})
|
112
115
|
if options[:methods]
|
@@ -124,7 +127,7 @@ module R18n
|
|
124
127
|
class_eval <<-EOS, __FILE__, __LINE__
|
125
128
|
def #{name}(*params)
|
126
129
|
unlocalized = self.class.unlocalized_getters(#{name.inspect})
|
127
|
-
|
130
|
+
r18n.locales.each do |locale|
|
128
131
|
code = locale.code
|
129
132
|
next unless unlocalized.has_key? code
|
130
133
|
result = send unlocalized[code]#{params}
|
@@ -133,19 +136,19 @@ module R18n
|
|
133
136
|
path = "\#{self.class.name}##{name}"
|
134
137
|
type = self.class.translation_types[#{name.inspect}]
|
135
138
|
if type
|
136
|
-
return
|
137
|
-
|
139
|
+
return r18n.filter_list.process(:all, type, result, locale,
|
140
|
+
path, params)
|
138
141
|
elsif result.is_a? String
|
139
142
|
result = TranslatedString.new(result, locale, path)
|
140
|
-
return
|
141
|
-
|
143
|
+
return r18n.filter_list.process_string(:all, result, path,
|
144
|
+
params)
|
142
145
|
else
|
143
146
|
return result
|
144
147
|
end
|
145
148
|
end
|
146
149
|
|
147
150
|
R18n::Untranslated.new("\#{self.class.name}\#", '#{name}',
|
148
|
-
|
151
|
+
r18n.locale, r18n.filter_list)
|
149
152
|
end
|
150
153
|
EOS
|
151
154
|
|
@@ -153,7 +156,7 @@ module R18n
|
|
153
156
|
class_eval <<-EOS, __FILE__, __LINE__
|
154
157
|
def #{name}=(*params)
|
155
158
|
unlocalized = self.class.unlocalized_setters(#{name.inspect})
|
156
|
-
|
159
|
+
r18n.locales.each do |locale|
|
157
160
|
code = locale.code
|
158
161
|
next unless unlocalized.has_key? code
|
159
162
|
return send unlocalized[code], *params
|
@@ -44,5 +44,19 @@ module R18n
|
|
44
44
|
def translated?
|
45
45
|
true
|
46
46
|
end
|
47
|
+
|
48
|
+
# Mark translated string as html safe, because R18n has own escape system.
|
49
|
+
def html_safe?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Override to_s to make string html safe if `html_safe` method is defined.
|
54
|
+
def to_s
|
55
|
+
if respond_to? :html_safe
|
56
|
+
html_safe
|
57
|
+
else
|
58
|
+
self
|
59
|
+
end
|
60
|
+
end
|
47
61
|
end
|
48
62
|
end
|
@@ -70,15 +70,15 @@ module R18n
|
|
70
70
|
# i18n.comments(0) #=> "no comments"
|
71
71
|
# i18n.comments(10) #=> "10 comments"
|
72
72
|
class Translation
|
73
|
-
# Create translation hash for +path+ with messages in +data+ for +locale+.
|
74
|
-
#
|
75
73
|
# This is internal a constructor. To load translation use
|
76
|
-
# <tt>R18n::
|
77
|
-
def initialize(
|
78
|
-
@
|
79
|
-
@
|
80
|
-
@
|
81
|
-
|
74
|
+
# <tt>R18n::I18n.new(locales, translations_dir)</tt>.
|
75
|
+
def initialize(locale, path = '', options = {})
|
76
|
+
@data = {}
|
77
|
+
@locale = locale
|
78
|
+
@path = path
|
79
|
+
@filters = options[:filters] || GlobalFilterList.instance
|
80
|
+
|
81
|
+
merge! options[:translations], options[:locale] if options[:translations]
|
82
82
|
end
|
83
83
|
|
84
84
|
# Add another hash with +translations+ for some +locale+. Current data is
|
@@ -89,17 +89,17 @@ module R18n
|
|
89
89
|
path = @path.empty? ? name : "#{@path}.#{name}"
|
90
90
|
case value
|
91
91
|
when Hash
|
92
|
-
value = Translation.new(@locale, path,
|
92
|
+
value = Translation.new(@locale, path,
|
93
|
+
:locale => locale, :translations => value, :filters => @filters)
|
93
94
|
when String
|
94
95
|
c = { :locale => locale, :path => path }
|
95
|
-
v =
|
96
|
+
v = @filters.process_string(:passive, value, c, [])
|
96
97
|
value = TranslatedString.new(v, locale, path)
|
97
98
|
when Typed
|
98
99
|
value.locale = locale
|
99
|
-
value.path
|
100
|
-
unless
|
101
|
-
value =
|
102
|
-
value.value, value.locale, value.path, {})
|
100
|
+
value.path = path
|
101
|
+
unless @filters.passive(value.type).empty?
|
102
|
+
value = @filters.process_typed(:passive, value, { })
|
103
103
|
end
|
104
104
|
end
|
105
105
|
@data[name] = value
|
@@ -111,12 +111,12 @@ module R18n
|
|
111
111
|
|
112
112
|
# Use untranslated filter to print path.
|
113
113
|
def to_s
|
114
|
-
|
114
|
+
@filters.process(:all, Untranslated, @path, @locale, @path,
|
115
115
|
[@path, '', @path])
|
116
116
|
end
|
117
117
|
|
118
118
|
# Return current translation keys.
|
119
|
-
def
|
119
|
+
def translation_keys
|
120
120
|
@data.keys
|
121
121
|
end
|
122
122
|
|
@@ -133,13 +133,12 @@ module R18n
|
|
133
133
|
value = @data[name.to_s]
|
134
134
|
case value
|
135
135
|
when TranslatedString
|
136
|
-
|
136
|
+
@filters.process_string(:active, value, @path, params)
|
137
137
|
when Typed
|
138
|
-
|
139
|
-
value.locale, value.path, params)
|
138
|
+
@filters.process_typed(:active, value, params)
|
140
139
|
when nil
|
141
140
|
translated = @path.empty? ? '' : "#{@path}."
|
142
|
-
Untranslated.new(translated, name.to_s, @locale)
|
141
|
+
Untranslated.new(translated, name.to_s, @locale, @filters)
|
143
142
|
else
|
144
143
|
value
|
145
144
|
end
|
@@ -46,10 +46,11 @@ module R18n
|
|
46
46
|
# Path, that exists in translation.
|
47
47
|
attr_reader :translated_path
|
48
48
|
|
49
|
-
def initialize(translated_path, untranslated_path, locale)
|
50
|
-
@translated_path
|
49
|
+
def initialize(translated_path, untranslated_path, locale, filters)
|
50
|
+
@translated_path = translated_path
|
51
51
|
@untranslated_path = untranslated_path
|
52
|
-
@locale
|
52
|
+
@locale = locale
|
53
|
+
@filters = filters
|
53
54
|
end
|
54
55
|
|
55
56
|
# Path to translation.
|
@@ -67,7 +68,7 @@ module R18n
|
|
67
68
|
|
68
69
|
def [](*params)
|
69
70
|
Untranslated.new(translated_path, "#{@untranslated_path}.#{params.first}",
|
70
|
-
@locale)
|
71
|
+
@locale, @filters)
|
71
72
|
end
|
72
73
|
|
73
74
|
def |(default)
|
@@ -75,8 +76,10 @@ module R18n
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def to_s
|
78
|
-
|
79
|
+
@filters.process(:all, Untranslated, path, @locale, path,
|
79
80
|
[@translated_path, @untranslated_path, path])
|
80
81
|
end
|
82
|
+
|
83
|
+
alias :to_str :to_s
|
81
84
|
end
|
82
85
|
end
|
data/lib/r18n-core/utils.rb
CHANGED
@@ -35,7 +35,11 @@ module R18n
|
|
35
35
|
|
36
36
|
# Escape HTML entries (<, >, &). Copy from HAML helper.
|
37
37
|
def self.escape_html(content)
|
38
|
-
|
38
|
+
if defined? ActiveSupport::SafeBuffer
|
39
|
+
ActiveSupport::SafeBuffer.new + content
|
40
|
+
else
|
41
|
+
content.to_s.gsub(/[><&]/) { |s| HTML_ENTRIES[s] }
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
# Invokes +block+ once for each key and value of +hash+. Creates a new hash
|
data/lib/r18n-core/version.rb
CHANGED
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
=end
|
20
20
|
|
21
21
|
require 'yaml'
|
22
|
-
require 'syck' if '1.8.' != RUBY_VERSION[0..3]
|
22
|
+
require 'syck' if '1.8.' != RUBY_VERSION[0..3] and RUBY_PLATFORM != 'java'
|
23
23
|
|
24
24
|
module R18n
|
25
25
|
module Loader
|
@@ -53,7 +53,7 @@ module R18n
|
|
53
53
|
def available
|
54
54
|
Dir.glob(File.join(@dir, '**/*.yml')).
|
55
55
|
map { |i| File.basename(i, '.yml') }.uniq.
|
56
|
-
map { |i| R18n
|
56
|
+
map { |i| R18n.locale(i) }
|
57
57
|
end
|
58
58
|
|
59
59
|
# Return Hash with translations for +locale+.
|
data/lib/r18n-core.rb
CHANGED
@@ -30,40 +30,46 @@ require dir.join('unsupported_locale').to_s
|
|
30
30
|
require dir.join('translated_string').to_s
|
31
31
|
require dir.join('untranslated').to_s
|
32
32
|
require dir.join('filters').to_s
|
33
|
+
require dir.join('filter_list').to_s
|
33
34
|
require dir.join('translation').to_s
|
34
35
|
require dir.join('yaml_loader').to_s
|
35
36
|
require dir.join('i18n').to_s
|
36
37
|
require dir.join('helpers').to_s
|
37
38
|
|
38
39
|
module R18n
|
40
|
+
autoload :Translated, 'r18n-core/translated'
|
41
|
+
|
39
42
|
class << self
|
40
43
|
|
41
|
-
# Set I18n object globally.
|
42
|
-
|
44
|
+
# Set I18n object globally. You can miss translation +places+, it will be
|
45
|
+
# taken from <tt>R18n.default_places</tt>.
|
46
|
+
def set(i18n = nil, places = R18n.default_places, &block)
|
43
47
|
if block_given?
|
44
48
|
@setter = block
|
45
|
-
@i18n
|
49
|
+
@i18n = nil
|
46
50
|
elsif i18n.is_a? I18n
|
47
51
|
@i18n = i18n
|
48
52
|
else
|
49
|
-
@i18n = I18n.new(i18n,
|
53
|
+
@i18n = I18n.new(i18n, places)
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
53
57
|
# Set I18n object to current thread.
|
54
58
|
def thread_set(i18n = nil, &block)
|
55
59
|
if block_given?
|
56
|
-
|
57
|
-
|
60
|
+
thread[:r18n_setter] = block
|
61
|
+
thread[:r18n_i18n] = nil
|
58
62
|
else
|
59
|
-
|
63
|
+
thread[:r18n_i18n] = i18n
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
67
|
# Get I18n object for current thread.
|
64
68
|
def get
|
65
|
-
|
66
|
-
(
|
69
|
+
thread[:r18n_i18n] ||
|
70
|
+
(thread[:r18n_setter] && thread_set(thread[:r18n_setter].call)) ||
|
71
|
+
@i18n ||
|
72
|
+
(@setter && set(@setter.call))
|
67
73
|
end
|
68
74
|
|
69
75
|
# Delete I18n object from current thread and global variable.
|
@@ -87,6 +93,46 @@ module R18n
|
|
87
93
|
get.l(*params)
|
88
94
|
end
|
89
95
|
|
96
|
+
# Return I18n object for +locale+. Useful to temporary change locale,
|
97
|
+
# for example, to show text in locales list:
|
98
|
+
#
|
99
|
+
# - R18n.available_locales.each do |locale|
|
100
|
+
# - R18n.change(locale).t.language_title
|
101
|
+
def change(locale)
|
102
|
+
locale = locale.code if locale.is_a? Locale
|
103
|
+
exists = get ? get.locales.map { |i| i.code } : []
|
104
|
+
places = get ? get.translation_places : R18n.default_places
|
105
|
+
R18n::I18n.new([locale] + exists, places)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Return Locale object by locale code. It’s shortcut for
|
109
|
+
# <tt>R18n::Locale.load(code)</tt>.
|
110
|
+
def locale(code)
|
111
|
+
R18n::Locale.load(code)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Return Array of locales with available translations. You can miss
|
115
|
+
# translation +places+, it will be taken from <tt>R18n.default_places</tt>.
|
116
|
+
def available_locales(places = R18n.default_places)
|
117
|
+
R18n::I18n.convert_places(places).map { |i| i.available }.flatten.uniq
|
118
|
+
end
|
119
|
+
|
120
|
+
# Default places for <tt>R18n.set</tt> and <tt>R18n.available_locales</tt>.
|
121
|
+
#
|
122
|
+
# You can set block to calculate places dynamically:
|
123
|
+
# R18n.default_places { settings.i18n_places }
|
124
|
+
attr_accessor :default_places
|
125
|
+
|
126
|
+
def default_places(&block)
|
127
|
+
if block_given?
|
128
|
+
@default_places = block
|
129
|
+
elsif @default_places.is_a? Proc
|
130
|
+
@default_places.call
|
131
|
+
else
|
132
|
+
@default_places
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
90
136
|
# Default loader class, which will be used if you didn’t send loader to
|
91
137
|
# +I18n.new+ (object with +available+ and +load+ methods).
|
92
138
|
attr_accessor :default_loader
|
@@ -99,8 +145,9 @@ module R18n
|
|
99
145
|
attr_accessor :cache
|
100
146
|
end
|
101
147
|
|
102
|
-
|
103
|
-
self.
|
104
|
-
|
105
|
-
self.
|
148
|
+
dir = Pathname(__FILE__).dirname.expand_path
|
149
|
+
self.default_loader = R18n::Loader::YAML
|
150
|
+
self.default_places = nil
|
151
|
+
self.extension_places = [Loader::YAML.new(dir + '../base')]
|
152
|
+
self.cache = {}
|
106
153
|
end
|
data/locales/ca.rb
CHANGED
data/locales/cs.rb
CHANGED
data/locales/en-au.rb
CHANGED
data/locales/en-gb.rb
CHANGED
data/locales/en-us.rb
CHANGED