r18n-core 0.3.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +11 -0
- data/README.rdoc +225 -53
- data/lib/r18n-core/filters.rb +34 -34
- data/lib/r18n-core/i18n.rb +110 -46
- data/lib/r18n-core/locale.rb +109 -103
- data/lib/r18n-core/translated.rb +9 -4
- data/lib/r18n-core/translated_string.rb +10 -0
- data/lib/r18n-core/translation.rb +55 -99
- data/lib/r18n-core/unsupported_locale.rb +1 -13
- data/lib/r18n-core/untranslated.rb +18 -16
- data/lib/r18n-core/utils.rb +0 -12
- data/lib/r18n-core/version.rb +1 -1
- data/lib/r18n-core/yaml_loader.rb +67 -0
- data/lib/r18n-core.rb +25 -3
- data/locales/cs.rb +30 -16
- data/locales/de.rb +21 -0
- data/locales/en-us.rb +9 -4
- data/locales/en.rb +35 -20
- data/locales/eo.rb +20 -0
- data/locales/es.rb +20 -0
- data/locales/fr.rb +24 -9
- data/locales/it.rb +21 -9
- data/locales/kk.rb +26 -0
- data/locales/pl.rb +30 -18
- data/locales/pt-br.rb +24 -0
- data/locales/ru.rb +30 -12
- data/locales/zh.rb +19 -0
- data/spec/filters_spec.rb +24 -7
- data/spec/i18n_spec.rb +137 -50
- data/spec/locale_spec.rb +91 -53
- data/spec/locales/cs_spec.rb +9 -7
- data/spec/locales/pl_spec.rb +8 -9
- data/spec/locales/ru_spec.rb +9 -9
- data/spec/r18n_spec.rb +32 -13
- data/spec/spec_helper.rb +28 -4
- data/spec/translated_spec.rb +1 -1
- data/spec/translation_spec.rb +33 -67
- data/spec/translations/two/en.yml +0 -1
- data/spec/yaml_loader_spec.rb +33 -0
- metadata +11 -16
- data/locales/cs.yml +0 -26
- data/locales/de.yml +0 -26
- data/locales/en-us.yml +0 -10
- data/locales/en.yml +0 -26
- data/locales/eo.yml +0 -26
- data/locales/es.yml +0 -26
- data/locales/fr.yml +0 -26
- data/locales/it.yml +0 -26
- data/locales/kk.yml +0 -26
- data/locales/pl.yml +0 -26
- data/locales/pt-br.yml +0 -26
- data/locales/ru.yml +0 -26
- data/locales/zh.yml +0 -26
data/ChangeLog
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.4 (D-Day)
|
2
|
+
* Rails I18n compatibility.
|
3
|
+
* Rewrite a lot of core code to fast and cleanup version.
|
4
|
+
* Custom translation loaders.
|
5
|
+
* Add reload! method to I18n.
|
6
|
+
* Add t and l helpers to Sinatra and desktop plugins.
|
7
|
+
* Syntax sugar for default values.
|
8
|
+
* Named variables.
|
9
|
+
* New locale API.
|
10
|
+
* Change API for extension translations.
|
11
|
+
|
1
12
|
== 0.3.2 (Pidgin)
|
2
13
|
* Print path of untranslated string by filters.
|
3
14
|
* Add Italian locale (by Guido De Rosa).
|
data/README.rdoc
CHANGED
@@ -1,26 +1,150 @@
|
|
1
1
|
= R18n
|
2
2
|
|
3
|
-
R18n is a i18n tool to translate your Ruby application
|
3
|
+
R18n is a i18n tool to translate your Ruby application to several languages.
|
4
4
|
|
5
|
-
Use <tt>sinatra-r18n</tt> or teamon’s <tt>merb_i18n</tt> to
|
6
|
-
<tt>r18n-desktop</tt> to localize desktop
|
5
|
+
Use <tt>r18n-rails</tt>, <tt>sinatra-r18n</tt> or teamon’s <tt>merb_i18n</tt> to
|
6
|
+
localize Web applications and <tt>r18n-desktop</tt> to localize desktop
|
7
|
+
application.
|
7
8
|
|
8
9
|
== Features
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
=== Ruby-style Syntax
|
12
|
+
R18n uses hierarchical not English-centrist YAML format for translations by
|
13
|
+
default:
|
14
|
+
|
15
|
+
user:
|
16
|
+
edit: Edit user
|
17
|
+
name: User name is %1
|
18
|
+
count: !!pl
|
19
|
+
1: There is 1 user
|
20
|
+
n: There are %1 users
|
21
|
+
|
22
|
+
To access translation you can call methods with same names:
|
23
|
+
|
24
|
+
t.user.edit #=> "Edit user"
|
25
|
+
t.user.name('John') #=> "User name is John"
|
26
|
+
t.user.count(5) #=> "There are 5 users"
|
27
|
+
|
28
|
+
t.not.exists | 'default' #=> "default"
|
29
|
+
t.not.exists.translated? #=> false
|
30
|
+
|
31
|
+
If translation key has name of Object method you can use another way:
|
32
|
+
|
33
|
+
t[:methods] #=> "Methods"
|
34
|
+
|
35
|
+
=== Filters
|
36
|
+
|
37
|
+
You can add custom filters for some YAML type or any translated strings.
|
38
|
+
Filters are cascade and can communicate with each other.
|
39
|
+
|
40
|
+
R18n already has filters for HTML escaping, lambdas, Textile and Markdown:
|
41
|
+
|
42
|
+
hi: !!markdown
|
43
|
+
**Hi**, people!
|
44
|
+
greater: !!escape
|
45
|
+
1 < 2 is true
|
46
|
+
|
47
|
+
t.hi #=> "<p><strong>Hi</strong>, people!</p>"
|
48
|
+
t.greater #=> "1 < 2 is true"
|
49
|
+
|
50
|
+
=== Flexibility
|
51
|
+
|
52
|
+
Translation variables and pluralization (“1 comment”, “5 comments”) are filters
|
53
|
+
too. So you can extend or replace it. For example, you can use named variables
|
54
|
+
filter from <tt>r18n-rails-api</tt> gem:
|
55
|
+
|
56
|
+
greeting: "Hi, {{name}}"
|
57
|
+
|
58
|
+
R18n::Filters.on(:named_variables)
|
59
|
+
t.greeting(name: 'John') #=> "Hi, John"
|
60
|
+
|
61
|
+
=== Flexible Locales
|
62
|
+
|
63
|
+
Locale can extend Locale class, so locales are very flexible. For example,
|
64
|
+
English locale extend time formatters:
|
65
|
+
|
66
|
+
l Date.now, :full #=> "30th of November, 2009"
|
67
|
+
|
68
|
+
Or Russian has built-in different pluralization without any lambdas in YAML:
|
69
|
+
|
70
|
+
t.user.count(1) #=> "1 пользователь"
|
71
|
+
t.user.count(2) #=> "2 пользователя"
|
72
|
+
t.user.count(5) #=> "5 пользователей"
|
73
|
+
|
74
|
+
=== Loaders
|
75
|
+
|
76
|
+
R18n can load translations from any places, not just from YAML files. You just
|
77
|
+
need to create loader object with 2 methods: +available+ and +load+:
|
78
|
+
|
79
|
+
class DBLoader
|
80
|
+
def available
|
81
|
+
Translation.find(:all).map(&:locale)
|
82
|
+
end
|
83
|
+
def load(locale)
|
84
|
+
Translation.find(locale).to_hash
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
R18n.set R18n::I18n.new(user_locales, DBLoader.new)
|
89
|
+
|
90
|
+
You can also set a list of different translation places or set extension places,
|
91
|
+
which will be used only with application translation (useful for plugins).
|
92
|
+
|
93
|
+
=== Object Translation
|
94
|
+
|
95
|
+
You can translate any class, including ORM models:
|
96
|
+
|
97
|
+
require 'r18n-core/translated'
|
98
|
+
|
99
|
+
class Product < ActiveRecord::Base
|
100
|
+
include R18n::Translated
|
101
|
+
# Model has two usual property: title_en and title_ru
|
102
|
+
translations :title
|
103
|
+
end
|
104
|
+
|
105
|
+
# For English user
|
106
|
+
product.title #=> "Anthrax"
|
107
|
+
|
108
|
+
# For Russian user
|
109
|
+
product.title #=> "Сибирская язва"
|
110
|
+
|
111
|
+
=== Localization
|
112
|
+
|
113
|
+
R18n can localize numbers and time:
|
114
|
+
|
115
|
+
l -5000 #=> "−5,000"
|
116
|
+
l Time.now #=> "30/11/2009 14:36"
|
117
|
+
l Time.now, :full #=> "30th of November, 2009 14:37"
|
118
|
+
l Time.now - 60, :human #=> "1 minute ago"
|
119
|
+
|
120
|
+
=== Several User Languages
|
121
|
+
|
122
|
+
Lack of translation in user language isn’t exception for R18n (because
|
123
|
+
translation to not primary language done by enthusiasts, it can be out of date).
|
124
|
+
R18n just automatically take next user language (browser send a list of locales)
|
125
|
+
and for cultures with two officially languages (e.g., exUSSR) it take second
|
126
|
+
language (e.g., if translation isn’t available in Kazakh R18n will see in
|
127
|
+
Russian):
|
128
|
+
|
129
|
+
i18n = R18n::I18n.new(['kk', 'de'], 'dir/with/translations')
|
130
|
+
|
131
|
+
i18n.locales #=> [Locale kk (Қазақша), Locale de (Deutsch),
|
132
|
+
# Locale ru (Русский), Locale en (English)]
|
133
|
+
|
134
|
+
i18n.kazakh #=> "Қазақша", main user language
|
135
|
+
i18n.deutsch #=> "Deutsch", not in Kazakh, use next user locale
|
136
|
+
i18n.russian #=> "Русский", not in kk and de, use Kazakh sublocale
|
137
|
+
i18n.english #=> "English", not in any user locales, use default
|
138
|
+
|
139
|
+
=== Agnostic
|
140
|
+
|
141
|
+
R18n has a agnostic core package and plugins with out-of-box support for
|
142
|
+
Sinatra, Merb and desktop applications.
|
20
143
|
|
21
144
|
== Usage
|
22
145
|
|
23
146
|
=== Translation
|
147
|
+
|
24
148
|
Translation files use YAML format and has name like en.yml (English) or
|
25
149
|
en-us.yml (USA English dialect) with language/country code (RFC 3066).
|
26
150
|
|
@@ -43,18 +167,18 @@ In translation you can use:
|
|
43
167
|
To get translated string use method with key name or square brackets [] for
|
44
168
|
keys, which is same with Object methods (+class+, +inspect+, etc):
|
45
169
|
|
46
|
-
|
47
|
-
|
170
|
+
t.robot #=> "This is robot"
|
171
|
+
t[:robot] #=> "This is robot"
|
48
172
|
|
49
173
|
Translation may be hierarchical:
|
50
174
|
|
51
|
-
|
52
|
-
|
175
|
+
t.post.add #=> "Add post"
|
176
|
+
t[:post][:add] #=> "Add post"
|
53
177
|
|
54
178
|
If locale willn’t be found in user locale R18n will search it in they sublocales
|
55
179
|
or in another locale, which user know:
|
56
180
|
|
57
|
-
|
181
|
+
t.no.in.english #=> "В английском нет"
|
58
182
|
|
59
183
|
Translated string has +locale+ method and you can get it locale (Locale instance
|
60
184
|
or code string if locale is’t supported in R18n):
|
@@ -65,26 +189,36 @@ You can replace some parameters in translated string by put it as arguments:
|
|
65
189
|
|
66
190
|
name: "My name is %1"
|
67
191
|
|
68
|
-
|
192
|
+
t.name('John') #=> "My name is John"
|
69
193
|
|
70
194
|
Pluralizable messages get item count from first argument:
|
71
195
|
|
72
|
-
|
73
|
-
|
74
|
-
|
196
|
+
t.robots(0) #=> "No robots"
|
197
|
+
t.robots(1) #=> "One robot"
|
198
|
+
t.robots(50) #=> "50 robots"
|
75
199
|
|
76
|
-
If there isn’t pluralization for some number, translation will be use
|
200
|
+
If there isn’t pluralization for some number, translation will be use +n+. If
|
77
201
|
there isn’t locale file for translation, it will be use English pluralization
|
78
|
-
rule (0, 1 and
|
202
|
+
rule (0, 1 and +n+).
|
203
|
+
|
204
|
+
You can check, is message has translation:
|
205
|
+
|
206
|
+
t.post.add.translated? #=> true
|
207
|
+
t.not.exists.translated? #=> false
|
208
|
+
|
209
|
+
For untranslated strings you can set default value:
|
210
|
+
|
211
|
+
t.not.exists | 'default' #=> "default"
|
79
212
|
|
80
213
|
R18n already has translation for common words for most supported locales.
|
81
214
|
See <tt>base/</tt> in dir in gem.
|
82
215
|
|
83
|
-
|
84
|
-
|
85
|
-
|
216
|
+
t.yes #=> "Yes"
|
217
|
+
t.cancel #=> "Cancel"
|
218
|
+
t.delete #=> "Delete"
|
86
219
|
|
87
220
|
=== Filters
|
221
|
+
|
88
222
|
You can also add you own filter for translations: escape HTML entries, convert
|
89
223
|
from Markdown syntax, etc.
|
90
224
|
|
@@ -95,7 +229,7 @@ from Markdown syntax, etc.
|
|
95
229
|
content + '!'
|
96
230
|
end
|
97
231
|
|
98
|
-
|
232
|
+
t.filtered('_') #=> "This_content_will_be_processed_by_filter!"
|
99
233
|
|
100
234
|
You can also add global filters for all translated strings:
|
101
235
|
|
@@ -104,13 +238,14 @@ You can also add global filters for all translated strings:
|
|
104
238
|
end
|
105
239
|
|
106
240
|
==== HTML Escape
|
241
|
+
|
107
242
|
R18n contain 2 filters to escape HTML entries: by YAML type and global. If you
|
108
243
|
need to escape HTML in some translations, just set <tt>!!escape</tt> YAML type:
|
109
244
|
|
110
245
|
greater: !!escape
|
111
246
|
1 < 2 is true
|
112
247
|
|
113
|
-
|
248
|
+
t.greater #=> "1 < 2 is true"
|
114
249
|
|
115
250
|
If you develop web application and want to escape HTML in all translations, just
|
116
251
|
activate global escape filter:
|
@@ -124,31 +259,34 @@ disable escaping in some special value.
|
|
124
259
|
<b>Warning</b>
|
125
260
|
|
126
261
|
R18n::Filters.on(:global_escape_html)
|
127
|
-
|
262
|
+
t.warning #=> "<b>Warning</b>"
|
128
263
|
|
129
264
|
==== Markdown
|
265
|
+
|
130
266
|
To use Markdown in your translations you must install maruku gem:
|
131
267
|
|
132
268
|
hi: !!markdown
|
133
269
|
**Hi**, people!
|
134
270
|
|
135
|
-
|
271
|
+
t.hi #=> "<p><strong>Hi</strong>, people!</p>"
|
136
272
|
|
137
273
|
|
138
274
|
==== Textile
|
275
|
+
|
139
276
|
To use Textile in your translations you must install RedCloth gem:
|
140
277
|
|
141
278
|
alarm: !!textile
|
142
279
|
It will delete _all_ users!
|
143
280
|
|
144
|
-
|
281
|
+
t.alarm #=> "<p>It will delete <em>all</em> users!</p>"
|
145
282
|
|
146
283
|
==== Lambdas
|
284
|
+
|
147
285
|
You can use lambdas in your translations.
|
148
286
|
|
149
287
|
sum: !!proc |x, y| x + y
|
150
288
|
|
151
|
-
|
289
|
+
t.sum(1, 2) #=> 3
|
152
290
|
|
153
291
|
If it isn’t secure in your application (for example, user can change
|
154
292
|
translations), you can disable it:
|
@@ -156,9 +294,10 @@ translations), you can disable it:
|
|
156
294
|
R18n::Filters.off(:procedure)
|
157
295
|
|
158
296
|
=== Localization
|
297
|
+
|
159
298
|
You can print number and float according to the rules of the user locale:
|
160
299
|
|
161
|
-
|
300
|
+
l -12000.5 #=> "−12,000.5"
|
162
301
|
|
163
302
|
Number and float formatters will also put real typographic minus and put
|
164
303
|
non-break thin spaces (for locale, which use it as digit separator).
|
@@ -166,17 +305,18 @@ non-break thin spaces (for locale, which use it as digit separator).
|
|
166
305
|
You can translate months and week days names in Time, Date and DateTime by
|
167
306
|
+strftime+ method:
|
168
307
|
|
169
|
-
|
308
|
+
l Time.now, '%B' #=> "September"
|
170
309
|
|
171
310
|
R18n has some time formats for locales: <tt>:human</tt>, <tt>:full</tt> and
|
172
311
|
<tt>:standard</tt> (by default):
|
173
312
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
313
|
+
l Time.now, :human #=> "now"
|
314
|
+
l Time.now, :full #=> "August 9th, 2009 21:47"
|
315
|
+
l Time.now #=> "08/09/2009 21:41"
|
316
|
+
l Time.now.to_date #=> "08/09/2009"
|
178
317
|
|
179
318
|
=== Model
|
319
|
+
|
180
320
|
You can add i18n support to any classes, including ORM models:
|
181
321
|
|
182
322
|
require 'r18n-core/translated'
|
@@ -206,6 +346,7 @@ You can add i18n support to any classes, including ORM models:
|
|
206
346
|
See R18n::Translated for documentation.
|
207
347
|
|
208
348
|
=== Locale
|
349
|
+
|
209
350
|
All supported locales are storage in R18n gem at +locales+ dir. If you want to
|
210
351
|
add your locale, please write me to andrey@sitnik.ru.
|
211
352
|
|
@@ -223,37 +364,68 @@ You can get from locale:
|
|
223
364
|
|
224
365
|
locale.ltr? #=> true
|
225
366
|
|
226
|
-
* Week start day (
|
367
|
+
* Week start day (+:monday+ or +:sunday+):
|
368
|
+
|
369
|
+
locale.week_start #=> :sunday
|
370
|
+
|
371
|
+
=== Loaders
|
372
|
+
|
373
|
+
You can load translations from any ways, not just from YAML files. To load
|
374
|
+
translation you must create loader class with 2 methods:
|
375
|
+
* <tt>available</tt> – return array of locales of available translations;
|
376
|
+
* <tt>load(locale)</tt> – return Hash of translation.
|
377
|
+
And put it instance to <tt>R18n::I18n.new</tt>:
|
378
|
+
|
379
|
+
R18n.set R18n::I18n.new('en', MyLoader.new(loader_param))
|
380
|
+
|
381
|
+
You can set your loader as default and pass to <tt>R18n::I18n.new</tt> only
|
382
|
+
constructor argument:
|
383
|
+
|
384
|
+
R18n.default_loader = MyLoader
|
385
|
+
R18n.set R18n::I18n.new('en', loader_param)
|
386
|
+
|
387
|
+
If you want to load translation with some type for filter, use
|
388
|
+
<tt>R18n::Typed</tt> struct:
|
389
|
+
|
390
|
+
# Loader load method return something like:
|
391
|
+
{ 'users' => R18n::Typed.new('pl', { 1 => '1 user', 'n' => '%1 users' }) }
|
227
392
|
|
228
|
-
|
393
|
+
# To use pluralization filter (+pl+ type):
|
394
|
+
t.users(5) #=> "5 users"
|
395
|
+
|
396
|
+
=== Extension Translations
|
397
|
+
|
398
|
+
For r18n plugin you can add loaders with translations, which will be used with
|
399
|
+
application translations. For example, DB plugin may place translations for
|
400
|
+
error messages in extension dir. R18n contain translations for base words as
|
401
|
+
extension dir too.
|
402
|
+
|
403
|
+
R18n.extension_places << R18n::Loader::YAML.new('./error_messages/')
|
404
|
+
|
405
|
+
== Add Locale
|
229
406
|
|
230
|
-
== Add locale
|
231
407
|
If R18n hasn’t locale file for your language, please add it. It’s very simple:
|
232
|
-
* Create in locales/ file _code_.
|
408
|
+
* Create in locales/ file _code_.rb for your language and describe locale.
|
233
409
|
Just copy from another locale and change different values.
|
234
|
-
* If your language is dialect or base on another (as American English (en-US)
|
235
|
-
base on English (en)) write <tt>include: _base_locale_</tt> and similar
|
236
|
-
values can be deleted.
|
237
410
|
* If in your country people mostly know another language (like in exUSSR
|
238
|
-
countries people know Russian),
|
239
|
-
<tt>sublocales
|
240
|
-
<tt>sublocales: [en]</tt>. For dialect put base locale to +sublocales+ too.
|
411
|
+
countries people know Russian), add
|
412
|
+
<tt>sublocales %{_another_locale_ en}</tt>.
|
241
413
|
* Create in base/ file _code_.yml for your language and translate base messages.
|
242
414
|
Just copy file from language, which you know, and rewrite values.
|
243
415
|
* If you language need some special logic (for example, different pluralization
|
244
|
-
or time formatters) you can
|
245
|
-
_code_.rb and write R18n::Locales::_Code_ class, which must extend
|
246
|
-
R18n::Locale.
|
416
|
+
or time formatters) you can extend Locale class methods.
|
247
417
|
* Push files by GitHub (http://github.com/ai/r18n) or just write e-mail with
|
248
418
|
this files to me (andrey@sitnik.ru).
|
249
419
|
|
250
420
|
_Code_ is RFC 3066 code for your language (for example, “en” for English and
|
251
|
-
“
|
421
|
+
“fr-CA” for Canadian French). You can send to my e-mail any questions (on
|
252
422
|
http://sitnik.ru you find another contact addresses).
|
253
423
|
|
254
424
|
== License
|
425
|
+
|
255
426
|
R18n is licensed under the GNU Lesser General Public License version 3.
|
256
427
|
You can read it in LICENSE file or in http://www.gnu.org/licenses/lgpl.html.
|
257
428
|
|
258
429
|
== Author
|
430
|
+
|
259
431
|
Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
data/lib/r18n-core/filters.rb
CHANGED
@@ -51,17 +51,17 @@ module R18n
|
|
51
51
|
# OpenStruct and you can add you own parameter to cross-filter communications:
|
52
52
|
#
|
53
53
|
# R18n::Filters.add(String, :hide_truth) do |content, config|
|
54
|
-
# return content if config
|
54
|
+
# return content if config[:censorship_check]
|
55
55
|
#
|
56
|
-
# if content.scan(CENSORSHIP_WORDS[config
|
56
|
+
# if content.scan(CENSORSHIP_WORDS[config[:locale]]).empty?
|
57
57
|
# content
|
58
58
|
# else
|
59
|
-
# "Error in #{config
|
59
|
+
# "Error in #{config[:path]}"
|
60
60
|
# end
|
61
61
|
# end
|
62
62
|
#
|
63
63
|
# R18n::Filters.add('passed', :show_lie) do |content, config|
|
64
|
-
# config
|
64
|
+
# config[:censorship_check] = true
|
65
65
|
# content
|
66
66
|
# end
|
67
67
|
#
|
@@ -99,30 +99,31 @@ module R18n
|
|
99
99
|
@by_type ||= Hash.new([])
|
100
100
|
end
|
101
101
|
|
102
|
-
# Process +
|
103
|
-
def process(
|
104
|
-
|
105
|
-
when Numeric, NilClass, FalseClass, TrueClass, Symbol
|
106
|
-
else
|
107
|
-
translation = translation.clone
|
108
|
-
end
|
109
|
-
config = OpenStruct.new(:locale => locale, :path => path)
|
102
|
+
# Process +value+ by global filters and filters for special +type+.
|
103
|
+
def process(type, value, locale, path, params)
|
104
|
+
config = { :locale => locale, :path => path }
|
110
105
|
|
111
|
-
|
112
|
-
filters = Filters.enabled[type]
|
113
|
-
filters.each { |f| translation = f.call(translation, config, *params)}
|
114
|
-
end
|
106
|
+
Filters.enabled[type].each { |f| value = f.call(value, config, *params)}
|
115
107
|
|
116
|
-
if
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
return TranslatedString.new(translation, locale, path)
|
108
|
+
if value.is_a? String
|
109
|
+
value = TranslatedString.new(value, locale, path)
|
110
|
+
process_string(value, config, params)
|
121
111
|
else
|
122
|
-
|
112
|
+
value
|
123
113
|
end
|
124
114
|
end
|
125
115
|
|
116
|
+
# Process +value+ by global filters.
|
117
|
+
def process_string(value, config, params)
|
118
|
+
if config.is_a? String
|
119
|
+
config = { :locale => value.locale, :path => config }
|
120
|
+
end
|
121
|
+
Filters.enabled[String].each do |f|
|
122
|
+
value = f.call(value, config, *params)
|
123
|
+
end
|
124
|
+
value
|
125
|
+
end
|
126
|
+
|
126
127
|
# Add new filter for +type+ with +name+ and return filter object. You
|
127
128
|
# can use String class as +type+ to add global filter for all translated
|
128
129
|
# string.
|
@@ -196,20 +197,19 @@ module R18n
|
|
196
197
|
end
|
197
198
|
|
198
199
|
Filters.add('pl', :pluralization) do |content, config, param|
|
199
|
-
|
200
|
-
|
201
|
-
|
200
|
+
if param.is_a? Numeric
|
201
|
+
type = config[:locale].pluralize(param)
|
202
|
+
type = 'n' if not content.has_key? type
|
203
|
+
content[type]
|
204
|
+
else
|
205
|
+
content
|
206
|
+
end
|
202
207
|
end
|
203
208
|
|
204
209
|
Filters.add(String, :variables) do |content, config, *params|
|
205
210
|
content = content.clone
|
206
211
|
params.each_with_index do |param, i|
|
207
|
-
|
208
|
-
param = config.locale.format_float(param)
|
209
|
-
elsif param.is_a? Integer
|
210
|
-
param = config.locale.format_integer(param)
|
211
|
-
end
|
212
|
-
content.gsub! "%#{i+1}", param.to_s
|
212
|
+
content.gsub! "%#{i+1}", config[:locale].localize(param)
|
213
213
|
end
|
214
214
|
content
|
215
215
|
end
|
@@ -219,17 +219,17 @@ module R18n
|
|
219
219
|
end
|
220
220
|
|
221
221
|
Filters.add('escape', :escape_html) do |content, config|
|
222
|
-
config
|
222
|
+
config[:dont_escape_html] = true
|
223
223
|
Utils.escape_html(content)
|
224
224
|
end
|
225
225
|
|
226
226
|
Filters.add('html', :dont_escape_html) do |content, config|
|
227
|
-
config
|
227
|
+
config[:dont_escape_html] = true
|
228
228
|
content
|
229
229
|
end
|
230
230
|
|
231
231
|
Filters.add(String, :global_escape_html) do |content, config|
|
232
|
-
if config
|
232
|
+
if config[:dont_escape_html]
|
233
233
|
content
|
234
234
|
else
|
235
235
|
Utils.escape_html(content)
|