r18n-core 0.3.2 → 0.4
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.
- 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)
|