r18n-core 0.4.14 → 1.0.0
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/.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/.yardopts
CHANGED
data/ChangeLog
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
== 1.0.0 (Bangkok)
|
2
|
+
* Add R18n.default_places.
|
3
|
+
* Rails SafeBuffer support.
|
4
|
+
* Allow in Rails app to put filters to app/i18n reload them in development.
|
5
|
+
* Move R18n::I18n.available_locales to R18n.available_locales.
|
6
|
+
* Rename _keys to translation_keys.
|
7
|
+
* Use Kramdown instead of Maruku for Markdown.
|
8
|
+
* Allow to use R18n for Rails without mailer.
|
9
|
+
* Allow to overwrite I18n object for models.
|
10
|
+
* Autoload R18n::Translated.
|
11
|
+
* Set default locale to R18n on Rails start to easy use in Rails console.
|
12
|
+
* Use env language in Rails console.
|
13
|
+
* Mark untranslated part as red in Rails console.
|
14
|
+
* Allow to temporary change locale by R18n.change.
|
15
|
+
* Add R18n.locale shortcut.
|
16
|
+
* Allow return from setter block locale code, instead of I18n object.
|
17
|
+
* Allow to set custom filters for I18n object.
|
18
|
+
* Add Galician locale (by Eduard Giménez).
|
19
|
+
* Add Traditional Chinese and Simplified Chinese (by Francis Chong).
|
20
|
+
* Fix Norsk locale (by Peter Haza).
|
21
|
+
|
1
22
|
== 0.4.14 (üç)
|
2
23
|
* Fix support for Ruby 1.9.3.
|
3
24
|
* Added Turkish locale (by Ahmet Özkaya).
|
data/LICENSE
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
the terms and conditions of version 3 of the GNU General Public
|
11
11
|
License, supplemented by the additional permissions listed below.
|
12
12
|
|
13
|
-
0. Additional Definitions.
|
13
|
+
0. Additional Definitions.
|
14
14
|
|
15
15
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
16
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
@@ -111,7 +111,7 @@ the following:
|
|
111
111
|
a copy of the Library already present on the user's computer
|
112
112
|
system, and (b) will operate properly with a modified version
|
113
113
|
of the Library that is interface-compatible with the Linked
|
114
|
-
Version.
|
114
|
+
Version.
|
115
115
|
|
116
116
|
e) Provide Installation Information, but only if you would otherwise
|
117
117
|
be required to provide such information under section 6 of the
|
data/README.md
ADDED
@@ -0,0 +1,456 @@
|
|
1
|
+
# R18n
|
2
|
+
|
3
|
+
R18n is an i18n tool to translate your Ruby application into several languages.
|
4
|
+
|
5
|
+
Use `r18n-rails` or `sinatra-r18n` to localize Web applications and
|
6
|
+
`r18n-desktop` to localize desktop application.
|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
* Nice Ruby-style syntax.
|
11
|
+
* Filters.
|
12
|
+
* Model Translation (or any Ruby object).
|
13
|
+
* Autodetect user locales.
|
14
|
+
* Flexible locales.
|
15
|
+
* Total flexibility.
|
16
|
+
|
17
|
+
See full features in [main README](https://github.com/ai/r18n/blob/master/README.md).
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
To add i18n support to your app, you can use the particular plugin for your
|
22
|
+
environment: `r18n-rails`, `sinatra-r18n` or `r18n-desktop`.
|
23
|
+
|
24
|
+
If you develop you own plugin or want to use only core gem, you will need to
|
25
|
+
set default translation places and current locale:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
R18n.default_places = 'path/to/translations'
|
29
|
+
R18n.set('en')
|
30
|
+
```
|
31
|
+
|
32
|
+
You can use `R18n.t` to get translations and `R18n.l` to localize times and
|
33
|
+
numbers. But more useful is to add helpers to fast access the R18n:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
include R18n::Helpers
|
37
|
+
|
38
|
+
t.yes #=> "Yes"
|
39
|
+
l Time.now, :human #=> "now"
|
40
|
+
|
41
|
+
r18n.locale.code #=> "en"
|
42
|
+
```
|
43
|
+
|
44
|
+
To set locale only for current thread use `R18n.thread_set`.
|
45
|
+
|
46
|
+
### Translation
|
47
|
+
|
48
|
+
Translation files are in YAML format by default and have names like
|
49
|
+
`en.yml` (English) or `en-us.yml` (USA English dialect) with
|
50
|
+
language/country code (RFC 3066).
|
51
|
+
|
52
|
+
In your translation files you can use:
|
53
|
+
|
54
|
+
* Strings
|
55
|
+
|
56
|
+
```yaml
|
57
|
+
robot: This is a robot
|
58
|
+
percent: "Percent sign (%)"
|
59
|
+
```
|
60
|
+
|
61
|
+
* Numbers
|
62
|
+
|
63
|
+
```yaml
|
64
|
+
number: 123
|
65
|
+
float: 12.45
|
66
|
+
```
|
67
|
+
|
68
|
+
* Pluralizable messages
|
69
|
+
|
70
|
+
```yaml
|
71
|
+
robots: !!pl
|
72
|
+
0: No robots
|
73
|
+
1: One robot
|
74
|
+
n: %1 robots
|
75
|
+
```
|
76
|
+
|
77
|
+
* Filters
|
78
|
+
|
79
|
+
```yaml
|
80
|
+
filtered: !!custom_type
|
81
|
+
This content will be processed by a filter
|
82
|
+
```
|
83
|
+
|
84
|
+
To get the translated string use a method with the key name or square brackets
|
85
|
+
[] for keys, which is the same with Object methods (`class`, `inspect`, etc):
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
t.robot #=> "This is a robot"
|
89
|
+
t[:robot] #=> "This is a robot"
|
90
|
+
```
|
91
|
+
|
92
|
+
Translation may be hierarchical:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
t.post.add #=> "Add post"
|
96
|
+
t[:post][:add] #=> "Add post"
|
97
|
+
```
|
98
|
+
|
99
|
+
If the locale isn’t found in the user’s requested locale, R18n will search for
|
100
|
+
it in sublocales or in another locale, which the user also can accept:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
t.not.in.english #=> "В английском нет"
|
104
|
+
```
|
105
|
+
|
106
|
+
The translated string has a `locale` method for determining its locale (Locale
|
107
|
+
instance or code string if locale is’t supported in R18n):
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
i18n.not.in.english.locale #=> Locale ru (Русский)
|
111
|
+
```
|
112
|
+
|
113
|
+
You can include parameters in the translated string by specifying arguments:
|
114
|
+
|
115
|
+
```yaml
|
116
|
+
name: My name is %1
|
117
|
+
```
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
t.name('John') #=> "My name is John"
|
121
|
+
```
|
122
|
+
|
123
|
+
Pluralizable messages get their item count from the first argument:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
t.robots(0) #=> "No robots"
|
127
|
+
t.robots(1) #=> "One robot"
|
128
|
+
t.robots(50) #=> "50 robots"
|
129
|
+
```
|
130
|
+
|
131
|
+
If there isn’t a pluralization for a particular number, translation will be use
|
132
|
+
`n`. If there isn’t a locale file for translation, it will use the English
|
133
|
+
pluralization rule (`0`, `1` and `n`).
|
134
|
+
|
135
|
+
You can check if the key has a translation:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
t.post.add.translated? #=> true
|
139
|
+
t.not.exists.translated? #=> false
|
140
|
+
```
|
141
|
+
|
142
|
+
You can set a default value for untranslated strings:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
t.not.exists | 'default' #=> "default"
|
146
|
+
```
|
147
|
+
|
148
|
+
You can query the translation keys:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
t.counties.translation_keys.each do |county|
|
152
|
+
puts t.counties[county]
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
156
|
+
R18n already has translations for common words for most built in locales.
|
157
|
+
See `base/` the source.
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
t.yes #=> "Yes"
|
161
|
+
t.cancel #=> "Cancel"
|
162
|
+
t.delete #=> "Delete"
|
163
|
+
```
|
164
|
+
|
165
|
+
### Filters
|
166
|
+
|
167
|
+
You can also add you own filters for translations: escape HTML entities, convert
|
168
|
+
from Markdown syntax, etc. Filters can be passive, only being processed when
|
169
|
+
loaded.
|
170
|
+
|
171
|
+
```yaml
|
172
|
+
friendship: !!gender
|
173
|
+
f: She adds a friend
|
174
|
+
m: He adds a friend
|
175
|
+
```
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
R18n::Filters.add('gender', :user_gender) do |content, config, user|
|
179
|
+
if user.female?
|
180
|
+
content['f']
|
181
|
+
else
|
182
|
+
content['m']
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
t.friendship(anne) #=> "She adds a friend"
|
187
|
+
```
|
188
|
+
|
189
|
+
To create a filter you pass the following to `R18n::Filters.add`:
|
190
|
+
|
191
|
+
* Filter target. YAML type (`!!type`), `String` for all translations of
|
192
|
+
`R18n::Untranslated` for missing translations.
|
193
|
+
* Optional filter name, to disable, enable or delete it later by
|
194
|
+
`R18n::Filters.off`, `R18n::Filters.on` and
|
195
|
+
`R18n::Filters.delete`.
|
196
|
+
* Hash with options:
|
197
|
+
* `:passive => true` to filter translations only on load;
|
198
|
+
* `:position` within the list of current filters of this type
|
199
|
+
(by default a new filter will be inserted into last position).
|
200
|
+
|
201
|
+
The filter will receive at least two arguments:
|
202
|
+
* Translation (possibly already filtered by other filters for this type earlier
|
203
|
+
in the list).
|
204
|
+
* A Hash with translation `locale` and `path`.
|
205
|
+
* Parameters from translation request will be in the remaining arguments.
|
206
|
+
|
207
|
+
#### HTML Escape
|
208
|
+
|
209
|
+
R18n contains 2 filters to escape HTML entities: by YAML type and global. If you
|
210
|
+
need to escape HTML in some translations, just set `!!escape` YAML type:
|
211
|
+
|
212
|
+
```yaml
|
213
|
+
greater: !!escape
|
214
|
+
1 < 2 is true
|
215
|
+
```
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
t.greater #=> "1 < 2 is true"
|
219
|
+
```
|
220
|
+
|
221
|
+
If you develop web application and want to escape HTML in all translations, just
|
222
|
+
activate the global escape filter:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
R18n::Filters.on(:global_escape_html)
|
226
|
+
```
|
227
|
+
|
228
|
+
If you enable global HTML escape, you may still use `!!html` YAML type to
|
229
|
+
disable escaping on some values:
|
230
|
+
|
231
|
+
```yaml
|
232
|
+
warning: !!html
|
233
|
+
<b>Warning</b>
|
234
|
+
```
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
R18n::Filters.on(:global_escape_html)
|
238
|
+
t.warning #=> "<b>Warning</b>"
|
239
|
+
```
|
240
|
+
|
241
|
+
#### Markdown
|
242
|
+
|
243
|
+
To use Markdown in your translations you must install the Kramdown gem:
|
244
|
+
|
245
|
+
```yaml
|
246
|
+
hi: !!markdown
|
247
|
+
**Hi**, people!
|
248
|
+
```
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
t.hi #=> "<p><strong>Hi</strong>, people!</p>"
|
252
|
+
```
|
253
|
+
|
254
|
+
#### Textile
|
255
|
+
|
256
|
+
To use Textile in your translations you must install the RedCloth gem:
|
257
|
+
|
258
|
+
```yaml
|
259
|
+
alarm: !!textile
|
260
|
+
It will delete _all_ users!
|
261
|
+
```
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
t.alarm #=> "<p>It will delete <em>all</em> users!</p>"
|
265
|
+
```
|
266
|
+
|
267
|
+
#### Lambdas
|
268
|
+
|
269
|
+
You can use lambdas in your translations.
|
270
|
+
|
271
|
+
```yaml
|
272
|
+
sum: !!proc |x, y| x + y
|
273
|
+
```
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
t.sum(1, 2) #=> 3
|
277
|
+
```
|
278
|
+
|
279
|
+
If this is unsafe in your application (for example, user can change
|
280
|
+
translations), you can disable it:
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
R18n::Filters.off(:procedure)
|
284
|
+
```
|
285
|
+
|
286
|
+
### Localization
|
287
|
+
|
288
|
+
You can print numbers and floats according to the rules of the user locale:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
l -12000.5 #=> "−12,000.5"
|
292
|
+
```
|
293
|
+
|
294
|
+
Number and float formatters will also put real typographic minus and put
|
295
|
+
non-breakable thin spaces (for locale, which use it as digit separator).
|
296
|
+
|
297
|
+
You can translate months and week day names in Time, Date and DateTime by the
|
298
|
+
`strftime` method:
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
l Time.now, '%B' #=> "September"
|
302
|
+
```
|
303
|
+
|
304
|
+
R18n has some built-in time formats for locales: `:human`, `:full` and
|
305
|
+
`:standard` (the default):
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
l Time.now, :human #=> "now"
|
309
|
+
l Time.now, :full #=> "August 9th, 2009 21:47"
|
310
|
+
l Time.now #=> "08/09/2009 21:41"
|
311
|
+
l Time.now.to_date #=> "08/09/2009"
|
312
|
+
```
|
313
|
+
|
314
|
+
### Model
|
315
|
+
|
316
|
+
You can add i18n support to any classes, including ORM models (ActiveRecord,
|
317
|
+
DataMapper, MongoMapper, Mongoid or others):
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
class Product
|
321
|
+
include DataMapper::Resource
|
322
|
+
property :title_ru, String
|
323
|
+
property :title_en, String
|
324
|
+
|
325
|
+
include R18n::Translated
|
326
|
+
translations :title
|
327
|
+
end
|
328
|
+
|
329
|
+
# For example, user only knows Russian
|
330
|
+
|
331
|
+
# Set English (default) title
|
332
|
+
product.title_en = "Anthrax"
|
333
|
+
product.title #=> "Anthrax"
|
334
|
+
|
335
|
+
# Set value for user locale (Russian)
|
336
|
+
product.title = "Сибирская язва"
|
337
|
+
product.title #=> "Сибирская язва"
|
338
|
+
|
339
|
+
product.title_en #=> "Anthrax"
|
340
|
+
product.title_ru #=> "Сибирская язва"
|
341
|
+
```
|
342
|
+
|
343
|
+
See `R18n::Translated` for documentation.
|
344
|
+
|
345
|
+
### Locale
|
346
|
+
|
347
|
+
All supported locales are stored in R18n gem in `locales` directory. If you want
|
348
|
+
to add your locale, please fork this project and send a pull request or email me
|
349
|
+
at <andrey@sitnik.ru>.
|
350
|
+
|
351
|
+
To get information about a locale create an `R18n::Locale` instance:
|
352
|
+
|
353
|
+
```ruby
|
354
|
+
locale = R18n.locale('en')
|
355
|
+
```
|
356
|
+
|
357
|
+
You can then get the following from the locale:
|
358
|
+
|
359
|
+
* Locale title and RFC 3066 code:
|
360
|
+
|
361
|
+
```ruby
|
362
|
+
locale.title #=> "English"
|
363
|
+
locale.code #=> "en"
|
364
|
+
```
|
365
|
+
|
366
|
+
* Language direction (left to right, or right to left for Arabic and Hebrew):
|
367
|
+
|
368
|
+
```ruby
|
369
|
+
locale.ltr? #=> true
|
370
|
+
```
|
371
|
+
|
372
|
+
* Week start day (`:monday` or `:sunday`):
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
locale.week_start #=> :sunday
|
376
|
+
```
|
377
|
+
|
378
|
+
### Loaders
|
379
|
+
|
380
|
+
You can load translations from anywhere, not just from YAML files. To load
|
381
|
+
translation you must create loader class with 2 methods:
|
382
|
+
|
383
|
+
* `available` – return array of locales of available translations;
|
384
|
+
* `load(locale)` – return Hash of translation.
|
385
|
+
|
386
|
+
Pass its instance to `R18n.default_places` or `R18n.set(locales, loaders)`
|
387
|
+
|
388
|
+
```ruby
|
389
|
+
R18n.default_places = MyLoader.new(loader_param)
|
390
|
+
R18n.set('en')
|
391
|
+
```
|
392
|
+
|
393
|
+
You can set your default loader and pass it to `R18n.set` as the only
|
394
|
+
constructor argument:
|
395
|
+
|
396
|
+
```ruby
|
397
|
+
R18n.default_loader = MyLoader
|
398
|
+
R18n.default_places = loader_param
|
399
|
+
|
400
|
+
R18n.set('en')
|
401
|
+
R18n.set('en', different_loader_param)
|
402
|
+
```
|
403
|
+
|
404
|
+
If you want to load a translation with some type for filter, use
|
405
|
+
`R18n::Typed` struct:
|
406
|
+
|
407
|
+
```ruby
|
408
|
+
# Loader will return something like:
|
409
|
+
{ 'users' => R18n::Typed.new('pl', { 1 => '1 user', 'n' => '%1 users' }) }
|
410
|
+
|
411
|
+
# To use pluralization filter ("pl" type):
|
412
|
+
t.users(5) #=> "5 users"
|
413
|
+
```
|
414
|
+
|
415
|
+
### Extension Translations
|
416
|
+
|
417
|
+
For r18n plugin you can add loaders with translations, which will be used with
|
418
|
+
application translations. For example, DB plugin may place translations for
|
419
|
+
error messages in extension directory. R18n contain translations for base words
|
420
|
+
as extension directory too.
|
421
|
+
|
422
|
+
```ruby
|
423
|
+
R18n.extension_places << R18n::Loader::YAML.new('./error_messages/')
|
424
|
+
```
|
425
|
+
|
426
|
+
## Add Locale
|
427
|
+
|
428
|
+
If R18n hasn’t got locale file for your language, please add it. It’s very
|
429
|
+
simple:
|
430
|
+
|
431
|
+
* Create the file <tt><i>code</i>.rb</tt> in the `locales/` directory for your
|
432
|
+
language and describe locale. Just copy from another locale and change the
|
433
|
+
values.
|
434
|
+
* If your country has alternate languages (for example, in exUSSR countries
|
435
|
+
most people also know Russian), add
|
436
|
+
<tt>sublocales %w{<i>another_locale</i> en}</tt>.
|
437
|
+
* Create in `base/` file <tt><i>code</i>.yml</tt> for your language and
|
438
|
+
translate the base messages. Just copy file from language, which you know,
|
439
|
+
and rewrite values.
|
440
|
+
* If your language needs some special logic (for example, different
|
441
|
+
pluralization or time formatters) you can extend `R18n::Locale` class methods.
|
442
|
+
* Send a pull request via GitHub <http://github.com/ai/r18n> or just write email
|
443
|
+
with the files to me <andrey@sitnik.ru>.
|
444
|
+
|
445
|
+
*Code* is RFC 3066 code for your language (for example, “en” for English and
|
446
|
+
“fr-CA” for Canadian French). Email me with any questions you may have, you will
|
447
|
+
find other contact addresses at http://sitnik.ru.
|
448
|
+
|
449
|
+
## License
|
450
|
+
|
451
|
+
R18n is licensed under the GNU Lesser General Public License version 3.
|
452
|
+
See the LICENSE file or http://www.gnu.org/licenses/lgpl.html.
|
453
|
+
|
454
|
+
## Author
|
455
|
+
|
456
|
+
Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
data/Rakefile
CHANGED
data/base/gl.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
ok: 'OK'
|
2
|
+
save: 'Gardar'
|
3
|
+
cancel: 'Cancelar'
|
4
|
+
'yes': 'Sí'
|
5
|
+
'no': 'Non'
|
6
|
+
exit: 'Deixar'
|
7
|
+
delete: 'Borrar'
|
8
|
+
|
9
|
+
human_time:
|
10
|
+
after_days: !!pl
|
11
|
+
1: 'despois do %1 día'
|
12
|
+
n: 'tras %1 días'
|
13
|
+
tomorrow: 'mañá'
|
14
|
+
after_hours: !!pl
|
15
|
+
1: 'despois de %1 hora'
|
16
|
+
n: 'tras %1 horas'
|
17
|
+
after_minutes: !!pl
|
18
|
+
1: 'despois de %1 minuto'
|
19
|
+
n: 'tras %1 minutos'
|
20
|
+
now: 'agora'
|
21
|
+
today: 'hoxe'
|
22
|
+
minutes_ago: !!pl
|
23
|
+
1: '%1 minuto'
|
24
|
+
n: '%1 minutos'
|
25
|
+
hours_ago: !!pl
|
26
|
+
1: '%1 hora'
|
27
|
+
n: '%1 horas'
|
28
|
+
yesterday: 'ayer'
|
29
|
+
days_ago: !!pl
|
30
|
+
1: '%1 día'
|
31
|
+
n: '%1 días'
|
data/base/it.yml
CHANGED
@@ -0,0 +1,157 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
=begin
|
3
|
+
Filters for translations content.
|
4
|
+
|
5
|
+
Copyright (C) 2012 Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
6
|
+
|
7
|
+
This program is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the GNU Lesser General Public License as published by
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
This program is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU Lesser General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Lesser General Public License
|
18
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
=end
|
20
|
+
|
21
|
+
module R18n
|
22
|
+
# Superclass for +GlobalFilterList+ and +CustomFilterList+ with filters
|
23
|
+
# processing.
|
24
|
+
class FilterList
|
25
|
+
# Process +value+ by filters in +enabled+.
|
26
|
+
def process(filters_type, type, value, locale, path, params)
|
27
|
+
config = { :locale => locale, :path => path }
|
28
|
+
|
29
|
+
enabled(filters_type, type).each do |filter|
|
30
|
+
value = filter.call(value, config, *params)
|
31
|
+
end
|
32
|
+
|
33
|
+
if value.is_a? String
|
34
|
+
value = TranslatedString.new(value, locale, path)
|
35
|
+
process_string(filters_type, value, config, params)
|
36
|
+
else
|
37
|
+
value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Shortcut ot process `R18n::Typed`.
|
42
|
+
def process_typed(filters_type, typed_value, params)
|
43
|
+
process(filters_type,
|
44
|
+
typed_value.type,
|
45
|
+
typed_value.value,
|
46
|
+
typed_value.locale,
|
47
|
+
typed_value.path,
|
48
|
+
params)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Process +value+ by global filters in +enabled+.
|
52
|
+
def process_string(filters_type, value, config, params)
|
53
|
+
if config.is_a? String
|
54
|
+
config = { :locale => value.locale, :path => config }
|
55
|
+
end
|
56
|
+
enabled(filters_type, String).each do |f|
|
57
|
+
value = f.call(value, config, *params)
|
58
|
+
end
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
62
|
+
# Array of enabled filters with +filters_type+ for +type+.
|
63
|
+
def enabled(filters_type, type)
|
64
|
+
if filters_type == :passive
|
65
|
+
passive(type)
|
66
|
+
elsif filters_type == :active
|
67
|
+
active(type)
|
68
|
+
else
|
69
|
+
all(type)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# List of enable passive filters.
|
74
|
+
def passive(type)
|
75
|
+
[]
|
76
|
+
end
|
77
|
+
|
78
|
+
# List of enable active filters.
|
79
|
+
def active(type)
|
80
|
+
[]
|
81
|
+
end
|
82
|
+
|
83
|
+
# List of enable filters.
|
84
|
+
def all(type)
|
85
|
+
[]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Filter list for I18n object with only global filters.
|
90
|
+
class GlobalFilterList < FilterList
|
91
|
+
include Singleton
|
92
|
+
|
93
|
+
def passive(type)
|
94
|
+
Filters.passive_enabled[type]
|
95
|
+
end
|
96
|
+
|
97
|
+
def active(type)
|
98
|
+
Filters.active_enabled[type]
|
99
|
+
end
|
100
|
+
|
101
|
+
def all(type)
|
102
|
+
Filters.enabled[type]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Filter list for I18n object with custom disabled/enabled filters.
|
107
|
+
class CustomFilterList < FilterList
|
108
|
+
|
109
|
+
def initialize(on, off)
|
110
|
+
@on = Array(on).map { |i| Filters.defined[i] }
|
111
|
+
@off = Array(off).map { |i| Filters.defined[i] }
|
112
|
+
@changed_types = (@on + @off).map { |i| i.types }.flatten.uniq
|
113
|
+
|
114
|
+
@changed_passive = (@on + @off).reject { |i| !i.passive? }.
|
115
|
+
map { |i| i.types }.flatten.uniq
|
116
|
+
@changed_active = (@on + @off).reject { |i| i.passive? }.
|
117
|
+
map { |i| i.types }.flatten.uniq
|
118
|
+
|
119
|
+
@on_by_type = {}
|
120
|
+
@on.each do |filter|
|
121
|
+
filter.types.each do |type|
|
122
|
+
@on_by_type[type] ||= []
|
123
|
+
@on_by_type[type] << filter
|
124
|
+
end
|
125
|
+
end
|
126
|
+
@off_by_type = {}
|
127
|
+
@off.each do |filter|
|
128
|
+
filter.types.each do |type|
|
129
|
+
@off_by_type[type] ||= []
|
130
|
+
@off_by_type[type] << filter
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def passive(type)
|
136
|
+
enabled = Filters.passive_enabled[type]
|
137
|
+
return enabled unless @changed_passive.include? type
|
138
|
+
enabled = enabled.reject { |i| @off_by_type[type].include? i }
|
139
|
+
enabled += @on_by_type[type].reject { |i| !i.passive }
|
140
|
+
end
|
141
|
+
|
142
|
+
def active(type)
|
143
|
+
enabled = Filters.active_enabled[type]
|
144
|
+
return enabled unless @changed_active.include? type
|
145
|
+
enabled = enabled.reject { |i| @off_by_type[type].include? i }
|
146
|
+
enabled += @on_by_type[type].reject { |i| i.passive }
|
147
|
+
end
|
148
|
+
|
149
|
+
def all(type)
|
150
|
+
enabled = Filters.enabled[type]
|
151
|
+
return enabled unless @changed_types.include? type
|
152
|
+
enabled = enabled.reject { |i| @off_by_type[type].include? i }
|
153
|
+
enabled += @on_by_type[type]
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|