i18n 0.4.0 → 1.14.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +0 -0
- data/README.md +127 -0
- data/lib/i18n/backend/base.rb +189 -111
- data/lib/i18n/backend/cache.rb +58 -22
- data/lib/i18n/backend/cache_file.rb +36 -0
- data/lib/i18n/backend/cascade.rb +9 -10
- data/lib/i18n/backend/chain.rb +95 -42
- data/lib/i18n/backend/fallbacks.rb +68 -22
- data/lib/i18n/backend/flatten.rb +13 -8
- data/lib/i18n/backend/gettext.rb +33 -25
- data/lib/i18n/backend/interpolation_compiler.rb +12 -14
- data/lib/i18n/backend/key_value.rb +112 -10
- data/lib/i18n/backend/lazy_loadable.rb +184 -0
- data/lib/i18n/backend/memoize.rb +13 -7
- data/lib/i18n/backend/metadata.rb +12 -6
- data/lib/i18n/backend/pluralization.rb +64 -25
- data/lib/i18n/backend/simple.rb +44 -18
- data/lib/i18n/backend/transliterator.rb +43 -33
- data/lib/i18n/backend.rb +5 -3
- data/lib/i18n/config.rb +91 -10
- data/lib/i18n/exceptions.rb +118 -22
- data/lib/i18n/gettext/helpers.rb +14 -4
- data/lib/i18n/gettext/po_parser.rb +7 -7
- data/lib/i18n/gettext.rb +6 -5
- data/lib/i18n/interpolate/ruby.rb +53 -0
- data/lib/i18n/locale/fallbacks.rb +33 -26
- data/lib/i18n/locale/tag/parents.rb +8 -8
- data/lib/i18n/locale/tag/rfc4646.rb +0 -2
- data/lib/i18n/locale/tag/simple.rb +2 -4
- data/lib/i18n/locale.rb +2 -0
- data/lib/i18n/middleware.rb +17 -0
- data/lib/i18n/tests/basics.rb +58 -0
- data/lib/i18n/tests/defaults.rb +52 -0
- data/lib/i18n/tests/interpolation.rb +167 -0
- data/lib/i18n/tests/link.rb +66 -0
- data/lib/i18n/tests/localization/date.rb +122 -0
- data/lib/i18n/tests/localization/date_time.rb +103 -0
- data/lib/i18n/tests/localization/procs.rb +118 -0
- data/lib/i18n/tests/localization/time.rb +103 -0
- data/lib/i18n/tests/localization.rb +19 -0
- data/lib/i18n/tests/lookup.rb +81 -0
- data/lib/i18n/tests/pluralization.rb +35 -0
- data/lib/i18n/tests/procs.rb +66 -0
- data/lib/i18n/tests.rb +14 -0
- data/lib/i18n/utils.rb +55 -0
- data/lib/i18n/version.rb +3 -1
- data/lib/i18n.rb +200 -87
- metadata +64 -56
- data/CHANGELOG.textile +0 -135
- data/README.textile +0 -93
- data/lib/i18n/backend/active_record/missing.rb +0 -65
- data/lib/i18n/backend/active_record/store_procs.rb +0 -38
- data/lib/i18n/backend/active_record/translation.rb +0 -93
- data/lib/i18n/backend/active_record.rb +0 -61
- data/lib/i18n/backend/cldr.rb +0 -100
- data/lib/i18n/core_ext/hash.rb +0 -29
- data/lib/i18n/core_ext/string/interpolate.rb +0 -98
data/CHANGELOG.textile
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
h1. Changelog
|
2
|
-
|
3
|
-
h2. master
|
4
|
-
|
5
|
-
h2. 0.4.0 (2010-05-27)
|
6
|
-
|
7
|
-
* "The localization proc also receives the object as option":http://github.com/svenfuchs/i18n/commit/4a8cd9fa660daaa3078e24c5851353ca377d9213
|
8
|
-
|
9
|
-
h2. 0.4.0.beta1 (2010-05-03)
|
10
|
-
|
11
|
-
* "Renamed Fast backend to Memoize backend":http://github.com/svenfuchs/i18n/commit/f7f7dc12c00a19d3876223771e14f8671ff313cd
|
12
|
-
|
13
|
-
* "Deprecate {{}} as interpolation syntax":http://github.com/svenfuchs/i18n/commit/8894ee521ef5788c415b625a6daf522af4c416e0
|
14
|
-
|
15
|
-
* "Allow nil translation to be stored again":http://github.com/svenfuchs/i18n/commit/f2074f1e82d10c2e9a801c8cc2f2a0c7c30703ba
|
16
|
-
|
17
|
-
h2. 0.4.0.beta (2010-04-30)
|
18
|
-
|
19
|
-
* "Added a KeyValue backend":http://github.com/svenfuchs/i18n/commit/28ca5f53ade7f545f8c0804e93564d4686b416a4
|
20
|
-
|
21
|
-
* "Added transliteration support":http://github.com/svenfuchs/i18n/commit/928fdb4794959e779e90f360eb01ba043672d8d5
|
22
|
-
|
23
|
-
* "Create Flatten backend module to aid handling flatten translations":http://github.com/svenfuchs/i18n/commit/2ec9d6998aa8facd7b15a3ef47a96cf2471cd8a1
|
24
|
-
|
25
|
-
* "Decouple the external separator (used when storing translations) from the internal separator in Fast and ActiveRecord backends":http://github.com/svenfuchs/i18n/commit/274cb4daa0ca5e3b2bd23b45eb7f9fc58f75a79d
|
26
|
-
|
27
|
-
h2. 0.3.7 (2010-04-17)
|
28
|
-
|
29
|
-
* "Speed up I18n.normalize_keys by caching reused normalizations and producing less garbage":http://github.com/svenfuchs/i18n/commit/819dac0fea9c29e6545801aa107e63e355728cd4
|
30
|
-
|
31
|
-
h2. 0.3.6 (2010-03-23)
|
32
|
-
|
33
|
-
* "Move gettext po parser to lib":http://github.com/svenfuchs/i18n/commit/b2f038663b55727ac2327e6f07a46ba5d69d600c
|
34
|
-
|
35
|
-
* "Move I18n configuration to I18n.config":http://github.com/svenfuchs/i18n/commit/4a7baea86663ead8c681008c3e80a622f0546b07
|
36
|
-
|
37
|
-
h2. 0.3.5 (2010-02-26)
|
38
|
-
|
39
|
-
* "Delegate I18n.normalize_translation_keys to I18n.normalize_keys and deprecate
|
40
|
-
the former":http://github.com/svenfuchs/i18n/commit/7284b04d5f5dd9679cb68875515cdd0cdfc96fef
|
41
|
-
|
42
|
-
h2. 0.3.4 (2010-02-25)
|
43
|
-
|
44
|
-
* "Rename I18n.normalize_translation_keys to I18n.normalize_keys and finally make it public":http://github.com/svenfuchs/i18n/commit/20b05fe5802df6c90fb70a4e3760b2b851b791b3
|
45
|
-
|
46
|
-
* "Added CLDR supoprt":http://github.com/svenfuchs/i18n/commit/860eadf671a231e7f5dffb1bb27fa318ff7a8786
|
47
|
-
|
48
|
-
h2. 0.3.3 (2009-12-29)
|
49
|
-
|
50
|
-
* "Use lib/i18n/version":http://github.com/svenfuchs/i18n/commit/ff426c8e7a2438b814cb303adadec292dacb752e
|
51
|
-
|
52
|
-
* "Added a benchmark suite":http://github.com/svenfuchs/i18n/commit/f9b5b9b113097724638bdab96862ffa404e67e70
|
53
|
-
|
54
|
-
* "Ensure links can be handled recursively":http://github.com/svenfuchs/i18n/commit/2c50bd209f3fc24fe9dfa694c81be64340f09b7d
|
55
|
-
|
56
|
-
* "Make sure we can lookup false values as translation data":http://github.com/svenfuchs/i18n/commit/561c82ba4b8921d03bfdf56cb2d0c2f287629001
|
57
|
-
|
58
|
-
* "Added Fast backend module":http://github.com/svenfuchs/i18n/commit/bd2f09f0a251ca793b0e8ecc7e32177a2f091c23
|
59
|
-
|
60
|
-
* "Added InterpolationCompiler backend module":http://github.com/svenfuchs/i18n/commit/91810887d1abfb28996a9183bc9004678290d28b
|
61
|
-
|
62
|
-
h2. 0.3.2 (2009-12-12)
|
63
|
-
|
64
|
-
* "Added Cascade backend":http://github.com/svenfuchs/i18n/commit/8009aef293e9ef8564c9005090d8380feabcaf6f
|
65
|
-
|
66
|
-
h2. 0.3.1 (2009-12-11)
|
67
|
-
|
68
|
-
* "Add PoParser to gemspec":http://github.com/svenfuchs/i18n/commit/d6b2763f39c932f66adb039b96882a472f883c51
|
69
|
-
* "Enable custom separators for ActiveRecord backend":http://github.com/svenfuchs/i18n/commit/9341d3fcfc951cc31807ba672d2b5d90909ef3e5
|
70
|
-
* "Pass interpolation values to interpolation procs":http://github.com/svenfuchs/i18n/commit/39c2ed8fbad645671cd5520ce7ad0aeefe2b0cca
|
71
|
-
* "Fix that ngettext supports keys with dots":http://github.com/svenfuchs/i18n/commit/7362a43c34364d500de8899cfcca6bf1a5e6d1c8
|
72
|
-
|
73
|
-
h2. 0.3.0 (2009-11-30)
|
74
|
-
|
75
|
-
* "Gettext backend and helpers":http://github.com/svenfuchs/i18n/commit/35a1740d2f10b808548af352006950da4017e374
|
76
|
-
* "Metadata module":http://github.com/svenfuchs/i18n/commit/2677208555179b36fcbe958c0e8bc642cf5bc020
|
77
|
-
* "Basic ActiveRecord backend":http://github.com/svenfuchs/i18n/commit/786632d0b42de423ecf0969622efc87f1691e2a2
|
78
|
-
* "Set encoding to UTF8 for all files":http://github.com/svenfuchs/i18n/commit/9be3d4a311b5bf583eec5d39986176cc40c112f2
|
79
|
-
* "Chain backend":http://github.com/svenfuchs/i18n/commit/08259ffb88b3005403648d77bc1cbca0b92f3cf5
|
80
|
-
* "Backend/cache implementation":http://github.com/svenfuchs/i18n/commit/e7bf15351cd2e27f5972eb40e65a5dd6f4a0feed
|
81
|
-
* "Pluralization module":http://github.com/svenfuchs/i18n/commit/9ca4c9ed52d4706566a6abeb2d78722dcc5d4764
|
82
|
-
* "add and adapt Globalize2 fallback implementation":http://github.com/svenfuchs/i18n/commit/1b37a303b27d6222b17162804b06323e5628768f
|
83
|
-
* "move Simple backend implementation to a Base backend class and extend Simple from Base.":http://github.com/svenfuchs/i18n/commit/32ddc80a04e6aa247f6d6613bde7f78c73396cb4
|
84
|
-
|
85
|
-
h2. 0.2.0 (2009-07-12)
|
86
|
-
|
87
|
-
* "Allow using Ruby 1.9 syntax for string interpolation (API addition)":http://github.com/svenfuchs/i18n/commit/c6e0b06d512f2af57199a843a1d8a40241b32861
|
88
|
-
* "Allow configuring the default scope separator, allow to pass a custom scope separator(API addition)":http://github.com/svenfuchs/i18n/commit/5b75bfbc348061adc11e3790187a187275bfd471 (e.g. I18n.t(:'foo|bar', :separator => '|')
|
89
|
-
* "Pass :format option to #translate for #localize more useful lambda support":http://github.com/svenfuchs/i18n/commit/e277711b3c844fe7589b8d3f9af0f7d1b969a273
|
90
|
-
* "Refactor Simple backend #resolve to #default and #resolve for more consistency. Now allows to pass lambdas as defaults and re-resolve Symbols":http://github.com/svenfuchs/i18n/commit/8c4ce3d923ce5fa73e973fe28217e18165549aba
|
91
|
-
* "Add lambda support to #translate (API addition)":http://github.com/svenfuchs/i18n/commit/c90e62d8f7d3d5b78f34cfe328d871b58884f115
|
92
|
-
* "Add lambda support to #localize (API addition)":http://github.com/svenfuchs/i18n/commit/9d390afcf33f3f469bb95e6888147152f6cc7442
|
93
|
-
|
94
|
-
h2. 0.1.3 (2009-02-27)
|
95
|
-
|
96
|
-
* "Remove unnecessary string encoding handling in the i18n simple backend which made the backend break on Ruby 1.9":http://github.com/svenfuchs/i18n/commit/4c3a970783861a94f2e89f46714fb3434e4f4f8d
|
97
|
-
|
98
|
-
h2. 0.1.2 (2009-01-09)
|
99
|
-
|
100
|
-
* "added #available_locales (returns an array of locales for which translations are available)":http://github.com/svenfuchs/i18n/commit/411f8fe7c8f3f89e9b6b921fa62ed66cb92f3af4
|
101
|
-
* "flatten load_path before using it so that a nested array of paths won't throw up":http://github.com/svenfuchs/i18n/commit/d473a068a2b90aba98135deb225d6eb6d8104d70
|
102
|
-
|
103
|
-
h2. 0.1.1 (2008-11-20)
|
104
|
-
|
105
|
-
* "Use :'en' as a default locale (in favor of :'en-US')":http://github.com/svenfuchs/i18n/commit/c4b10b246aecf7da78cb2568dd0d2ab7e6b8a230
|
106
|
-
* "Add #reload! to Simple backend":http://github.com/svenfuchs/i18n/commit/36dd2bd9973b9e1559728749a9daafa44693e964
|
107
|
-
|
108
|
-
h2. 0.1.0 (2008-10-25)
|
109
|
-
|
110
|
-
* "Fix Simple backend to distinguish false from nil values":http://github.com/svenfuchs/i18n/commit/39d9a47da14b5f3ba126af48923af8c30e135166
|
111
|
-
* "Add #load_path to public api, add initialize to simple backend and remove #load_translations from public api":http://github.com/svenfuchs/i18n/commit/c4c5649e6bc8f020f1aaf5a5470bde048e22c82d
|
112
|
-
* "Speed up Backend::Simple#interpolate":http://github.com/svenfuchs/i18n/commit/9e1ac6bf8833304e036323ec9932b9f33c468a35
|
113
|
-
* "Remove #populate and #store_translations from public API":http://github.com/svenfuchs/i18n/commit/f4e514a80be7feb509f66824ee311905e2940900
|
114
|
-
* "Use :other instead of :many as a plural key":http://github.com/svenfuchs/i18n/commit/0f8f20a2552bf6a2aa758d8fdd62a7154e4a1bf6
|
115
|
-
* "Use a class instead of a module for Simple backend":http://github.com/svenfuchs/i18n/commit/08f051aa61320c17debde24a83268bc74e33b995
|
116
|
-
* "Make Simple backend #interpolate deal with non-ASCII string encodings":http://github.com/svenfuchs/i18n/commit/d84a3f3f55543c084d5dc5d1fed613b8df148789
|
117
|
-
* "Fix default arrays of non-existant keys returning the default array":http://github.com/svenfuchs/i18n/commit/6c04ca86c87f97dc78f07c2a4023644e5ba8b839
|
118
|
-
|
119
|
-
h2. Initial implementation (June/July 2008)
|
120
|
-
|
121
|
-
Initial implementation by "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs based on previous discussion/consensus of the rails-i18n team (alphabetical order) and many others:
|
122
|
-
|
123
|
-
* "Matt Aimonetti":http://railsontherun.com
|
124
|
-
* "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs
|
125
|
-
* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
|
126
|
-
* "Saimon Moore":http://saimonmoore.net
|
127
|
-
* "Stephan Soller":http://www.arkanis-development.de
|
128
|
-
|
129
|
-
h2. More information
|
130
|
-
|
131
|
-
* "Homepage":http://rails-i18n.org
|
132
|
-
* "Wiki":http://rails-i18n.org/wiki
|
133
|
-
* "Mailinglist":http://groups.google.com/group/rails-i18n
|
134
|
-
* "About the project/history":http://www.artweb-design.de/2008/7/18/finally-ruby-on-rails-gets-internationalized
|
135
|
-
* "Initial API Intro":http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api
|
data/README.textile
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
h1. Ruby I18n
|
2
|
-
|
3
|
-
Ruby Internationalization and localization solution.
|
4
|
-
|
5
|
-
Features:
|
6
|
-
|
7
|
-
* translation and localization
|
8
|
-
* interpolation of values to translations (Ruby 1.9 compatible syntax)
|
9
|
-
* pluralization (CLDR compatible)
|
10
|
-
* customizable transliteration to ASCII
|
11
|
-
* flexible defaults
|
12
|
-
* bulk lookup
|
13
|
-
* lambdas as translation data
|
14
|
-
* custom key/scope separator
|
15
|
-
* custom exception handlers
|
16
|
-
* extensible architecture with a swappable backend
|
17
|
-
|
18
|
-
Pluggable features:
|
19
|
-
|
20
|
-
* Cache
|
21
|
-
* Pluralization: lambda pluralizers stored as translation data
|
22
|
-
* Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation)
|
23
|
-
* Gettext support
|
24
|
-
* Translation metadata
|
25
|
-
|
26
|
-
Alternative backends:
|
27
|
-
|
28
|
-
* Chain
|
29
|
-
* ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs)
|
30
|
-
* KeyValue (uses active_support/json and cannot store procs)
|
31
|
-
|
32
|
-
For more information and lots of resources see: "http://rails-i18n.org/wiki":http://rails-i18n.org/wiki
|
33
|
-
|
34
|
-
h2. Installation
|
35
|
-
|
36
|
-
gem install i18n
|
37
|
-
|
38
|
-
h3. Installation on Rails < 2.3.5 (deprecated)
|
39
|
-
|
40
|
-
Up to version 2.3.4 Rails will not accept i18n gems > 0.1.3. There is an unpacked
|
41
|
-
gem inside of active_support/lib/vendor which gets loaded unless gem 'i18n', '~> 0.1.3'.
|
42
|
-
This requirement is relaxed in "6da03653":http://github.com/rails/rails/commit/6da03653
|
43
|
-
|
44
|
-
The new i18n gem can be loaded from vendor/plugins like this:
|
45
|
-
|
46
|
-
def reload_i18n!
|
47
|
-
raise "Move to i18n version 0.2.0 or greater" if Rails.version > "2.3.4"
|
48
|
-
|
49
|
-
$:.grep(/i18n/).each { |path| $:.delete(path) }
|
50
|
-
I18n::Backend.send :remove_const, "Simple"
|
51
|
-
$: << Rails.root.join('vendor', 'plugins', 'i18n', 'lib').to_s
|
52
|
-
end
|
53
|
-
|
54
|
-
Then you can `reload_i18n!` inside an i18n initializer.
|
55
|
-
|
56
|
-
h2. Tests
|
57
|
-
|
58
|
-
You can run tests both with
|
59
|
-
|
60
|
-
* `rake test` or just `rake`
|
61
|
-
* run any test file directly, e.g. `ruby test/api/simple_test.rb`
|
62
|
-
* run all tests with `ruby test/all.rb`
|
63
|
-
|
64
|
-
The structure of the test suite is a bit unusual as it uses modules to reuse
|
65
|
-
particular tests in different test cases.
|
66
|
-
|
67
|
-
The reason for this is that we need to enforce the I18n API across various
|
68
|
-
combinations of extensions. E.g. the Simple backend alone needs to support
|
69
|
-
the same API as any combination of feature and/or optimization modules included
|
70
|
-
to the Simple backend. We test this by reusing the same API defition (implemented
|
71
|
-
as test methods) in test cases with different setups.
|
72
|
-
|
73
|
-
You can find the test cases that enforce the API in test/api. And you can find
|
74
|
-
the API definition test methods in test/api/tests.
|
75
|
-
|
76
|
-
All other test cases (e.g. as defined in test/backend, test/core\_ext) etc.
|
77
|
-
follow the usual test setup and should be easy to grok.
|
78
|
-
|
79
|
-
h2. Authors
|
80
|
-
|
81
|
-
* "Sven Fuchs":http://www.artweb-design.de
|
82
|
-
* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
|
83
|
-
* "Stephan Soller":http://www.arkanis-development.de
|
84
|
-
* "Saimon Moore":http://saimonmoore.net
|
85
|
-
* "Matt Aimonetti":http://railsontherun.com
|
86
|
-
|
87
|
-
h2. Contributors
|
88
|
-
|
89
|
-
http://github.com/svenfuchs/i18n/contributors
|
90
|
-
|
91
|
-
h2. License
|
92
|
-
|
93
|
-
MIT License. See the included MIT-LICENSE file.
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# This extension stores translation stub records for missing translations to
|
2
|
-
# the database.
|
3
|
-
#
|
4
|
-
# This is useful if you have a web based translation tool. It will populate
|
5
|
-
# the database with untranslated keys as the application is being used. A
|
6
|
-
# translator can then go through these and add missing translations.
|
7
|
-
#
|
8
|
-
# Example usage:
|
9
|
-
#
|
10
|
-
# I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)
|
11
|
-
# I18n.backend = I18nChainBackend.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)
|
12
|
-
#
|
13
|
-
# Stub records for pluralizations will also be created for each key defined
|
14
|
-
# in i18n.plural.keys.
|
15
|
-
#
|
16
|
-
# For example:
|
17
|
-
#
|
18
|
-
# # en.yml
|
19
|
-
# en:
|
20
|
-
# i18n:
|
21
|
-
# plural:
|
22
|
-
# keys: [:zero, :one, :other]
|
23
|
-
#
|
24
|
-
# # pl.yml
|
25
|
-
# pl:
|
26
|
-
# i18n:
|
27
|
-
# plural:
|
28
|
-
# keys: [:zero, :one, :few, :other]
|
29
|
-
#
|
30
|
-
# It will also persist interpolation keys in Translation#interpolations so
|
31
|
-
# translators will be able to review and use them.
|
32
|
-
module I18n
|
33
|
-
module Backend
|
34
|
-
class ActiveRecord
|
35
|
-
module Missing
|
36
|
-
def store_default_translations(locale, key, options = {})
|
37
|
-
count, scope, default, separator = options.values_at(:count, *Base::RESERVED_KEYS)
|
38
|
-
separator ||= I18n.default_separator
|
39
|
-
|
40
|
-
keys = I18n.normalize_keys(locale, key, scope, separator)[1..-1]
|
41
|
-
key = keys.join(separator || I18n.default_separator)
|
42
|
-
|
43
|
-
unless ActiveRecord::Translation.locale(locale).lookup(key).exists?
|
44
|
-
interpolations = options.reject { |name, value| Base::RESERVED_KEYS.include?(name) }.keys
|
45
|
-
keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(separator) } : [key]
|
46
|
-
keys.each { |key| store_default_translation(locale, key, interpolations) }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def store_default_translation(locale, key, interpolations)
|
51
|
-
translation = ActiveRecord::Translation.new :locale => locale.to_s, :key => key
|
52
|
-
translation.interpolations = interpolations
|
53
|
-
translation.save
|
54
|
-
end
|
55
|
-
|
56
|
-
def translate(locale, key, options = {})
|
57
|
-
super
|
58
|
-
rescue I18n::MissingTranslationData => e
|
59
|
-
self.store_default_translations(locale, key, options)
|
60
|
-
raise e
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# This module is intended to be mixed into the ActiveRecord backend to allow
|
2
|
-
# storing Ruby Procs as translation values in the database.
|
3
|
-
#
|
4
|
-
# I18n.backend = I18n::Backend::ActiveRecord.new
|
5
|
-
# I18n::Backend::ActiveRecord::Translation.send(:include, I18n::Backend::ActiveRecord::StoreProcs)
|
6
|
-
#
|
7
|
-
# The StoreProcs module requires the ParseTree and ruby2ruby gems and therefor
|
8
|
-
# was extracted from the original backend.
|
9
|
-
#
|
10
|
-
# ParseTree is not compatible with Ruby 1.9.
|
11
|
-
|
12
|
-
begin
|
13
|
-
require 'ruby2ruby'
|
14
|
-
require 'parse_tree'
|
15
|
-
require 'parse_tree_extensions'
|
16
|
-
rescue LoadError => e
|
17
|
-
puts "can't use StoreProcs because: #{e.message}"
|
18
|
-
end
|
19
|
-
|
20
|
-
module I18n
|
21
|
-
module Backend
|
22
|
-
class ActiveRecord
|
23
|
-
module StoreProcs
|
24
|
-
def value=(v)
|
25
|
-
case v
|
26
|
-
when Proc
|
27
|
-
write_attribute(:value, v.to_ruby)
|
28
|
-
write_attribute(:is_proc, true)
|
29
|
-
else
|
30
|
-
write_attribute(:value, v)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
Translation.send(:include, self) if method(:to_s).respond_to?(:to_ruby)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
|
3
|
-
module I18n
|
4
|
-
module Backend
|
5
|
-
# ActiveRecord model used to store actual translations to the database.
|
6
|
-
#
|
7
|
-
# This model expects a table like the following to be already set up in
|
8
|
-
# your the database:
|
9
|
-
#
|
10
|
-
# create_table :translations do |t|
|
11
|
-
# t.string :locale
|
12
|
-
# t.string :key
|
13
|
-
# t.text :value
|
14
|
-
# t.text :interpolations
|
15
|
-
# t.boolean :is_proc, :default => false
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# This model supports to named scopes :locale and :lookup. The :locale
|
19
|
-
# scope simply adds a condition for a given locale:
|
20
|
-
#
|
21
|
-
# I18n::Backend::ActiveRecord::Translation.locale(:en).all
|
22
|
-
# # => all translation records that belong to the :en locale
|
23
|
-
#
|
24
|
-
# The :lookup scope adds a condition for looking up all translations
|
25
|
-
# that either start with the given keys (joined by an optionally given
|
26
|
-
# separator or I18n.default_separator) or that exactly have this key.
|
27
|
-
#
|
28
|
-
# # with translations present for :"foo.bar" and :"foo.baz"
|
29
|
-
# I18n::Backend::ActiveRecord::Translation.lookup(:foo)
|
30
|
-
# # => an array with both translation records :"foo.bar" and :"foo.baz"
|
31
|
-
#
|
32
|
-
# I18n::Backend::ActiveRecord::Translation.lookup([:foo, :bar])
|
33
|
-
# I18n::Backend::ActiveRecord::Translation.lookup(:"foo.bar")
|
34
|
-
# # => an array with the translation record :"foo.bar"
|
35
|
-
#
|
36
|
-
# When the StoreProcs module was mixed into this model then Procs will
|
37
|
-
# be stored to the database as Ruby code and evaluated when :value is
|
38
|
-
# called.
|
39
|
-
#
|
40
|
-
# Translation = I18n::Backend::ActiveRecord::Translation
|
41
|
-
# Translation.create \
|
42
|
-
# :locale => 'en'
|
43
|
-
# :key => 'foo'
|
44
|
-
# :value => lambda { |key, options| 'FOO' }
|
45
|
-
# Translation.find_by_locale_and_key('en', 'foo').value
|
46
|
-
# # => 'FOO'
|
47
|
-
class ActiveRecord
|
48
|
-
class Translation < ::ActiveRecord::Base
|
49
|
-
set_table_name 'translations'
|
50
|
-
attr_protected :is_proc, :interpolations
|
51
|
-
|
52
|
-
serialize :value
|
53
|
-
serialize :interpolations, Array
|
54
|
-
|
55
|
-
scope_method = ::ActiveRecord::VERSION::MAJOR == 2 ? :named_scope : :scope
|
56
|
-
|
57
|
-
send scope_method, :locale, lambda { |locale|
|
58
|
-
{ :conditions => { :locale => locale.to_s } }
|
59
|
-
}
|
60
|
-
|
61
|
-
send scope_method, :lookup, lambda { |keys, *separator|
|
62
|
-
column_name = connection.quote_column_name('key')
|
63
|
-
keys = Array(keys).map! { |key| key.to_s }
|
64
|
-
|
65
|
-
unless separator.empty?
|
66
|
-
warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " <<
|
67
|
-
"You can change the internal separator by overwriting FLATTEN_SEPARATOR."
|
68
|
-
end
|
69
|
-
|
70
|
-
namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%"
|
71
|
-
{ :conditions => ["#{column_name} IN (?) OR #{column_name} LIKE ?", keys, namespace] }
|
72
|
-
}
|
73
|
-
|
74
|
-
def self.available_locales
|
75
|
-
Translation.find(:all, :select => 'DISTINCT locale').map { |t| t.locale.to_sym }
|
76
|
-
end
|
77
|
-
|
78
|
-
def interpolates?(key)
|
79
|
-
self.interpolations.include?(key) if self.interpolations
|
80
|
-
end
|
81
|
-
|
82
|
-
def value
|
83
|
-
if is_proc
|
84
|
-
Kernel.eval(read_attribute(:value))
|
85
|
-
else
|
86
|
-
value = read_attribute(:value)
|
87
|
-
value == 'f' ? false : value
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'i18n/backend/base'
|
2
|
-
require 'i18n/backend/active_record/translation'
|
3
|
-
|
4
|
-
module I18n
|
5
|
-
module Backend
|
6
|
-
class ActiveRecord
|
7
|
-
autoload :Missing, 'i18n/backend/active_record/missing'
|
8
|
-
autoload :StoreProcs, 'i18n/backend/active_record/store_procs'
|
9
|
-
autoload :Translation, 'i18n/backend/active_record/translation'
|
10
|
-
|
11
|
-
module Implementation
|
12
|
-
include Base, Flatten
|
13
|
-
|
14
|
-
def available_locales
|
15
|
-
begin
|
16
|
-
Translation.available_locales
|
17
|
-
rescue ::ActiveRecord::StatementInvalid
|
18
|
-
[]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def store_translations(locale, data, options = {})
|
23
|
-
escape = options.fetch(:escape, true)
|
24
|
-
flatten_translations(locale, data, escape, false).each do |key, value|
|
25
|
-
Translation.locale(locale).lookup(expand_keys(key)).delete_all
|
26
|
-
Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
|
32
|
-
def lookup(locale, key, scope = [], options = {})
|
33
|
-
key = normalize_flat_keys(locale, key, scope, options[:separator])
|
34
|
-
result = Translation.locale(locale).lookup(key).all
|
35
|
-
|
36
|
-
if result.empty?
|
37
|
-
nil
|
38
|
-
elsif result.first.key == key
|
39
|
-
result.first.value
|
40
|
-
else
|
41
|
-
chop_range = (key.size + FLATTEN_SEPARATOR.size)..-1
|
42
|
-
result = result.inject({}) do |hash, r|
|
43
|
-
hash[r.key.slice(chop_range)] = r.value
|
44
|
-
hash
|
45
|
-
end
|
46
|
-
result.deep_symbolize_keys
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
|
51
|
-
def expand_keys(key)
|
52
|
-
key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, key|
|
53
|
-
keys << [keys.last, key].compact.join(FLATTEN_SEPARATOR)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
include Implementation
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/i18n/backend/cldr.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'cldr'
|
3
|
-
|
4
|
-
module I18n
|
5
|
-
module Backend
|
6
|
-
module Cldr
|
7
|
-
include ::Cldr::Format
|
8
|
-
|
9
|
-
def localize(locale, object, format = :default, options = {})
|
10
|
-
options[:as] ||= detect_type(object, options)
|
11
|
-
send(:"format_#{options[:as]}", locale, object, format, options)
|
12
|
-
end
|
13
|
-
|
14
|
-
def format_decimal(locale, object, format = :default, options = {})
|
15
|
-
formatter(locale, :decimal, format).apply(object, options)
|
16
|
-
end
|
17
|
-
|
18
|
-
def format_integer(locale, object, format = :default, options = {})
|
19
|
-
format_object(number, options.merge(:precision => 0))
|
20
|
-
end
|
21
|
-
|
22
|
-
def format_currency(locale, object, format = :default, options = {})
|
23
|
-
options.merge!(:currency => lookup_currency(locale, options[:currency], object)) if options[:currency].is_a?(Symbol)
|
24
|
-
formatter(locale, :currency, format).apply(object, options)
|
25
|
-
end
|
26
|
-
|
27
|
-
def format_percent(locale, object, format = :default, options = {})
|
28
|
-
formatter(locale, :percent, format).apply(object, options)
|
29
|
-
end
|
30
|
-
|
31
|
-
def format_date(locale, object, format = :default, options = {})
|
32
|
-
formatter(locale, :date, format).apply(object, options)
|
33
|
-
end
|
34
|
-
|
35
|
-
def format_time(locale, object, format = :default, options = {})
|
36
|
-
formatter(locale, :time, format).apply(object, options)
|
37
|
-
end
|
38
|
-
|
39
|
-
def format_datetime(locale, object, format = :default, options = {})
|
40
|
-
key = :"calendars.gregorian.formats.datetime.#{format}.pattern"
|
41
|
-
date = I18n.l(object, :format => options[:date_format] || format, :locale => locale, :as => :date)
|
42
|
-
time = I18n.l(object, :format => options[:time_format] || format, :locale => locale, :as => :time)
|
43
|
-
I18n.t(key, :date => date, :time => time, :locale => locale, :raise => true)
|
44
|
-
end
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
def detect_type(object, options)
|
49
|
-
options.has_key?(:currency) ? :currency : case object
|
50
|
-
when ::Numeric
|
51
|
-
:decimal
|
52
|
-
when ::Date, ::DateTime, ::Time
|
53
|
-
object.class.name.downcase.to_sym
|
54
|
-
else
|
55
|
-
raise_unspecified_format_type!
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def formatter(locale, type, format)
|
60
|
-
(@formatters ||= {})[:"#{locale}.#{type}.#{format}"] ||= begin
|
61
|
-
format = lookup_format(locale, type, format)
|
62
|
-
data = lookup_format_data(locale, type)
|
63
|
-
::Cldr::Format.const_get(type.to_s.camelize).new(format, data)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def lookup_format(locale, type, format)
|
68
|
-
key = case type
|
69
|
-
when :date, :time, :datetime
|
70
|
-
:"calendars.gregorian.formats.#{type}.#{format}.pattern"
|
71
|
-
else
|
72
|
-
:"numbers.formats.#{type}.patterns.#{format || :default}"
|
73
|
-
end
|
74
|
-
I18n.t(key, :locale => locale, :raise => true)
|
75
|
-
end
|
76
|
-
|
77
|
-
def lookup_format_data(locale, type)
|
78
|
-
key = case type
|
79
|
-
when :date, :time, :datetime
|
80
|
-
:'calendars.gregorian'
|
81
|
-
else
|
82
|
-
:'numbers.symbols'
|
83
|
-
end
|
84
|
-
I18n.t(key, :locale => locale, :raise => true)
|
85
|
-
end
|
86
|
-
|
87
|
-
def lookup_currency(locale, currency, count)
|
88
|
-
I18n.t(:"currencies.#{currency}", :locale => locale, :count => count)
|
89
|
-
end
|
90
|
-
|
91
|
-
def raise_unspecified_format_type!
|
92
|
-
raise ArgumentError.new("You have to specify a format type, e.g. :as => :number.")
|
93
|
-
end
|
94
|
-
|
95
|
-
def raise_unspecified_currency!
|
96
|
-
raise ArgumentError.new("You have to specify a currency, e.g. :currency => 'EUR'.")
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/lib/i18n/core_ext/hash.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
class Hash
|
2
|
-
def slice(*keep_keys)
|
3
|
-
h = {}
|
4
|
-
keep_keys.each { |key| h[key] = fetch(key) }
|
5
|
-
h
|
6
|
-
end unless Hash.method_defined?(:slice)
|
7
|
-
|
8
|
-
def except(*less_keys)
|
9
|
-
slice(*keys - less_keys)
|
10
|
-
end unless Hash.method_defined?(:except)
|
11
|
-
|
12
|
-
def deep_symbolize_keys
|
13
|
-
inject({}) { |result, (key, value)|
|
14
|
-
value = value.deep_symbolize_keys if value.is_a?(Hash)
|
15
|
-
result[(key.to_sym rescue key) || key] = value
|
16
|
-
result
|
17
|
-
}
|
18
|
-
end unless Hash.method_defined?(:deep_symbolize_keys)
|
19
|
-
|
20
|
-
# deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
21
|
-
MERGER = proc do |key, v1, v2|
|
22
|
-
Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
|
23
|
-
end
|
24
|
-
|
25
|
-
def deep_merge!(data)
|
26
|
-
merge!(data, &MERGER)
|
27
|
-
end unless Hash.method_defined?(:deep_merge!)
|
28
|
-
end
|
29
|
-
|