i18n 0.4.0.beta1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of i18n might be problematic. Click here for more details.
- data/CHANGELOG.textile +3 -1
- data/lib/i18n.rb +21 -9
- data/lib/i18n/backend/active_record.rb +2 -6
- data/lib/i18n/backend/base.rb +16 -59
- data/lib/i18n/backend/flatten.rb +6 -6
- data/lib/i18n/backend/key_value.rb +4 -7
- data/lib/i18n/backend/simple.rb +79 -14
- data/lib/i18n/version.rb +1 -1
- metadata +3 -4
data/CHANGELOG.textile
CHANGED
data/lib/i18n.rb
CHANGED
@@ -164,13 +164,13 @@ module I18n
|
|
164
164
|
# Transliterates UTF-8 characters to ASCII. By default this method will
|
165
165
|
# transliterate only Latin strings to an ASCII approximation:
|
166
166
|
#
|
167
|
-
#
|
167
|
+
# I18n.transliterate("Ærøskøbing")
|
168
168
|
# # => "AEroskobing"
|
169
169
|
#
|
170
|
-
#
|
170
|
+
# I18n.transliterate("日本語")
|
171
171
|
# # => "???"
|
172
172
|
#
|
173
|
-
# It's also possible to add support for per-locale transliterations.
|
173
|
+
# It's also possible to add support for per-locale transliterations. I18n
|
174
174
|
# expects transliteration rules to be stored at
|
175
175
|
# <tt>i18n.transliterate.rule</tt>.
|
176
176
|
#
|
@@ -206,12 +206,12 @@ module I18n
|
|
206
206
|
#
|
207
207
|
# Transliterating strings:
|
208
208
|
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
209
|
+
# I18n.locale = :en
|
210
|
+
# I18n.transliterate("Jürgen") # => "Jurgen"
|
211
|
+
# I18n.locale = :de
|
212
|
+
# I18n.transliterate("Jürgen") # => "Juergen"
|
213
|
+
# I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
|
214
|
+
# I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
|
215
215
|
def transliterate(*args)
|
216
216
|
options = args.pop if args.last.is_a?(Hash)
|
217
217
|
key = args.shift
|
@@ -232,6 +232,18 @@ module I18n
|
|
232
232
|
end
|
233
233
|
alias :l :localize
|
234
234
|
|
235
|
+
# Executes block with given I18n.locale set.
|
236
|
+
def with_locale(tmp_locale = nil)
|
237
|
+
if tmp_locale
|
238
|
+
current_locale = self.locale
|
239
|
+
self.locale = tmp_locale
|
240
|
+
end
|
241
|
+
yield
|
242
|
+
ensure
|
243
|
+
self.locale = current_locale if tmp_locale
|
244
|
+
end
|
245
|
+
|
246
|
+
|
235
247
|
# Merges the given locale, key and scope into a single array of keys.
|
236
248
|
# Splits keys that contain dots into multiple keys. Makes sure all
|
237
249
|
# keys are Symbols.
|
@@ -11,12 +11,7 @@ module I18n
|
|
11
11
|
module Implementation
|
12
12
|
include Base, Flatten
|
13
13
|
|
14
|
-
def reload!
|
15
|
-
end
|
16
|
-
|
17
14
|
def available_locales
|
18
|
-
init_translations unless initialized?
|
19
|
-
|
20
15
|
begin
|
21
16
|
Translation.available_locales
|
22
17
|
rescue ::ActiveRecord::StatementInvalid
|
@@ -25,7 +20,8 @@ module I18n
|
|
25
20
|
end
|
26
21
|
|
27
22
|
def store_translations(locale, data, options = {})
|
28
|
-
|
23
|
+
escape = options.fetch(:escape, true)
|
24
|
+
flatten_translations(locale, data, escape, false).each do |key, value|
|
29
25
|
Translation.locale(locale).lookup(expand_keys(key)).delete_all
|
30
26
|
Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value)
|
31
27
|
end
|
data/lib/i18n/backend/base.rb
CHANGED
@@ -9,33 +9,28 @@ module I18n
|
|
9
9
|
include I18n::Backend::Transliterator
|
10
10
|
|
11
11
|
RESERVED_KEYS = [:scope, :default, :separator, :resolve]
|
12
|
-
RESERVED_KEYS_PATTERN =
|
13
|
-
|
12
|
+
RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
|
13
|
+
DEPRECATED_INTERPOLATION_SYNTAX_PATTERN = /(\\)?\{\{([^\}]+)\}\}/
|
14
14
|
|
15
15
|
# Accepts a list of paths to translation files. Loads translations from
|
16
16
|
# plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
|
17
17
|
# for details.
|
18
18
|
def load_translations(*filenames)
|
19
|
+
filenames = I18n.load_path.flatten if filenames.empty?
|
19
20
|
filenames.each { |filename| load_file(filename) }
|
20
21
|
end
|
21
22
|
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# translations will be overwritten by new ones only at the deepest
|
25
|
-
# level of the hash.
|
23
|
+
# This method receives a locale, a data hash and options for storing translations.
|
24
|
+
# Should be implemented
|
26
25
|
def store_translations(locale, data, options = {})
|
27
|
-
|
28
|
-
translations[locale] ||= {}
|
29
|
-
|
30
|
-
data = data.deep_symbolize_keys
|
31
|
-
translations[locale].deep_merge!(data)
|
26
|
+
raise NotImplementedError
|
32
27
|
end
|
33
28
|
|
34
29
|
def translate(locale, key, options = {})
|
35
30
|
raise InvalidLocale.new(locale) unless locale
|
36
31
|
return key.map { |k| translate(locale, k, options) } if key.is_a?(Array)
|
37
32
|
|
38
|
-
entry = lookup
|
33
|
+
entry = key && lookup(locale, key, options[:scope], options)
|
39
34
|
|
40
35
|
if options.empty?
|
41
36
|
entry = resolve(locale, key, entry, options)
|
@@ -63,7 +58,7 @@ module I18n
|
|
63
58
|
if Symbol === format
|
64
59
|
key = format
|
65
60
|
type = object.respond_to?(:sec) ? 'time' : 'date'
|
66
|
-
format = I18n.t(:"#{type}.formats.#{key}", :
|
61
|
+
format = I18n.t(:"#{type}.formats.#{key}", options.merge(:raise => true, :object => object, :locale => locale))
|
67
62
|
end
|
68
63
|
|
69
64
|
# format = resolve(locale, object, format, options)
|
@@ -80,60 +75,21 @@ module I18n
|
|
80
75
|
object.strftime(format)
|
81
76
|
end
|
82
77
|
|
83
|
-
def initialized?
|
84
|
-
@initialized ||= false
|
85
|
-
end
|
86
|
-
|
87
78
|
# Returns an array of locales for which translations are available
|
88
79
|
# ignoring the reserved translation meta data key :i18n.
|
89
80
|
def available_locales
|
90
|
-
|
91
|
-
translations.inject([]) do |locales, (locale, data)|
|
92
|
-
locales << locale unless (data.keys - [:i18n]).empty?
|
93
|
-
locales
|
94
|
-
end
|
81
|
+
raise NotImplementedError
|
95
82
|
end
|
96
83
|
|
97
84
|
def reload!
|
98
|
-
@initialized = false
|
99
|
-
@translations = nil
|
100
85
|
@skip_syntax_deprecation = false
|
101
86
|
end
|
102
87
|
|
103
88
|
protected
|
104
89
|
|
105
|
-
|
106
|
-
load_translations(*I18n.load_path.flatten)
|
107
|
-
@initialized = true
|
108
|
-
end
|
109
|
-
|
110
|
-
def translations
|
111
|
-
@translations ||= {}
|
112
|
-
end
|
113
|
-
|
114
|
-
# Check if the key is valid and then initialize the translation and
|
115
|
-
# trigger the default lookup behavior.
|
116
|
-
def lookup!(locale, key, options)
|
117
|
-
return unless key
|
118
|
-
init_translations unless initialized?
|
119
|
-
lookup(locale, key, options[:scope], options)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Looks up a translation from the translations hash. Returns nil if
|
123
|
-
# eiher key is nil, or locale, scope or key do not exist as a key in the
|
124
|
-
# nested translations hash. Splits keys or scopes containing dots
|
125
|
-
# into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
|
126
|
-
# <tt>%w(currency format)</tt>.
|
90
|
+
# The method which actually looks up for the translation in the store.
|
127
91
|
def lookup(locale, key, scope = [], options = {})
|
128
|
-
|
129
|
-
|
130
|
-
keys.inject(translations) do |result, key|
|
131
|
-
key = key.to_sym
|
132
|
-
return nil unless result.is_a?(Hash) && result.has_key?(key)
|
133
|
-
result = result[key]
|
134
|
-
result = resolve(locale, key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
|
135
|
-
result
|
136
|
-
end
|
92
|
+
raise NotImplementedError
|
137
93
|
end
|
138
94
|
|
139
95
|
# Evaluates defaults.
|
@@ -162,7 +118,8 @@ module I18n
|
|
162
118
|
when Symbol
|
163
119
|
I18n.translate(subject, (options || {}).merge(:locale => locale, :raise => true))
|
164
120
|
when Proc
|
165
|
-
|
121
|
+
date_or_time = options.delete(:object) || object
|
122
|
+
resolve(locale, object, subject.call(date_or_time, options), options = {})
|
166
123
|
else
|
167
124
|
subject
|
168
125
|
end
|
@@ -175,7 +132,7 @@ module I18n
|
|
175
132
|
# and the second translation if it is equal to 1. Other backends can
|
176
133
|
# implement more flexible or complex pluralization rules.
|
177
134
|
def pluralize(locale, entry, count)
|
178
|
-
return entry unless entry.is_a?(Hash)
|
135
|
+
return entry unless entry.is_a?(Hash) && count
|
179
136
|
|
180
137
|
key = :zero if count == 0 && entry.has_key?(:zero)
|
181
138
|
key ||= count == 1 ? :one : :other
|
@@ -193,9 +150,9 @@ module I18n
|
|
193
150
|
# interpolation).
|
194
151
|
def interpolate(locale, string, values = {})
|
195
152
|
return string unless string.is_a?(::String) && !values.empty?
|
196
|
-
|
153
|
+
|
197
154
|
preserve_encoding(string) do
|
198
|
-
string = string.gsub(
|
155
|
+
string = string.gsub(DEPRECATED_INTERPOLATION_SYNTAX_PATTERN) do
|
199
156
|
escaped, key = $1, $2.to_sym
|
200
157
|
if escaped
|
201
158
|
"{{#{key}}}"
|
data/lib/i18n/backend/flatten.rb
CHANGED
@@ -3,7 +3,7 @@ module I18n
|
|
3
3
|
# This module contains several helpers to assist flattening translations.
|
4
4
|
# You may want to flatten translations for:
|
5
5
|
#
|
6
|
-
# 1) speed up lookups, as in the
|
6
|
+
# 1) speed up lookups, as in the Memoize backend;
|
7
7
|
# 2) In case you want to store translations in a data store, as in ActiveRecord backend;
|
8
8
|
#
|
9
9
|
# You can check both backends above for some examples.
|
@@ -51,12 +51,12 @@ module I18n
|
|
51
51
|
# >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind
|
52
52
|
# => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
|
53
53
|
#
|
54
|
-
def flatten_keys(hash, prev_key
|
54
|
+
def flatten_keys(hash, escape, prev_key=nil, &block)
|
55
55
|
hash.each_pair do |key, value|
|
56
|
-
key = escape_default_separator(key)
|
56
|
+
key = escape_default_separator(key) if escape
|
57
57
|
curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym
|
58
58
|
yield curr_key, value
|
59
|
-
flatten_keys(value, curr_key, &block) if value.is_a?(Hash)
|
59
|
+
flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -66,9 +66,9 @@ module I18n
|
|
66
66
|
#
|
67
67
|
# Nested hashes are included in the flattened hash just if subtree
|
68
68
|
# is true and Symbols are automatically stored as links.
|
69
|
-
def flatten_translations(locale, data, subtree
|
69
|
+
def flatten_translations(locale, data, escape, subtree)
|
70
70
|
hash = {}
|
71
|
-
flatten_keys(data) do |key, value|
|
71
|
+
flatten_keys(data, escape) do |key, value|
|
72
72
|
if value.is_a?(Hash)
|
73
73
|
hash[key] = value if subtree
|
74
74
|
else
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'i18n/backend/base'
|
3
4
|
require 'active_support/json'
|
4
5
|
|
@@ -47,6 +48,7 @@ module I18n
|
|
47
48
|
#
|
48
49
|
# I18n::Backend::KeyValue.new(@store, false)
|
49
50
|
#
|
51
|
+
# This is useful if you are using a KeyValue backend chained to a Simple backend.
|
50
52
|
class KeyValue
|
51
53
|
module Implementation
|
52
54
|
attr_accessor :store
|
@@ -57,12 +59,9 @@ module I18n
|
|
57
59
|
@store, @subtrees = store, subtrees
|
58
60
|
end
|
59
61
|
|
60
|
-
# Mute reload! since we really don't want to clean the database.
|
61
|
-
def reload!
|
62
|
-
end
|
63
|
-
|
64
62
|
def store_translations(locale, data, options = {})
|
65
|
-
|
63
|
+
escape = options.fetch(:escape, true)
|
64
|
+
flatten_translations(locale, data, escape, @subtrees).each do |key, value|
|
66
65
|
key = "#{locale}.#{key}"
|
67
66
|
|
68
67
|
case value
|
@@ -80,8 +79,6 @@ module I18n
|
|
80
79
|
end
|
81
80
|
|
82
81
|
def available_locales
|
83
|
-
init_translations unless initialized?
|
84
|
-
|
85
82
|
locales = @store.keys.map { |k| k =~ /\./; $` }
|
86
83
|
locales.uniq!
|
87
84
|
locales.compact!
|
data/lib/i18n/backend/simple.rb
CHANGED
@@ -1,22 +1,87 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# Stub class for the Simple backend. The actual implementation is provided by
|
4
|
-
# the backend Base class. This makes it easier to extend the Simple backend's
|
5
|
-
# behaviour by including modules. E.g.:
|
6
|
-
#
|
7
|
-
# module I18n::Backend::Pluralization
|
8
|
-
# def pluralize(*args)
|
9
|
-
# # extended pluralization logic
|
10
|
-
# super
|
11
|
-
# end
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
|
15
|
-
|
16
3
|
module I18n
|
17
4
|
module Backend
|
5
|
+
# A simple backend that reads translations from YAML files and stores them in
|
6
|
+
# an in-memory hash. Relies on the Base backend.
|
7
|
+
#
|
8
|
+
# The implementation is provided by a Implementation module allowing to easily
|
9
|
+
# extend Simple backend's behavior by including modules. E.g.:
|
10
|
+
#
|
11
|
+
# module I18n::Backend::Pluralization
|
12
|
+
# def pluralize(*args)
|
13
|
+
# # extended pluralization logic
|
14
|
+
# super
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
|
18
19
|
class Simple
|
19
|
-
|
20
|
+
module Implementation
|
21
|
+
include Base
|
22
|
+
|
23
|
+
def initialized?
|
24
|
+
@initialized ||= false
|
25
|
+
end
|
26
|
+
|
27
|
+
# Stores translations for the given locale in memory.
|
28
|
+
# This uses a deep merge for the translations hash, so existing
|
29
|
+
# translations will be overwritten by new ones only at the deepest
|
30
|
+
# level of the hash.
|
31
|
+
def store_translations(locale, data, options = {})
|
32
|
+
locale = locale.to_sym
|
33
|
+
translations[locale] ||= {}
|
34
|
+
data = data.deep_symbolize_keys
|
35
|
+
translations[locale].deep_merge!(data)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get available locales from the translations hash
|
39
|
+
def available_locales
|
40
|
+
init_translations unless initialized?
|
41
|
+
translations.inject([]) do |locales, (locale, data)|
|
42
|
+
locales << locale unless (data.keys - [:i18n]).empty?
|
43
|
+
locales
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Clean up translations hash and set initialized to false on reload!
|
48
|
+
def reload!
|
49
|
+
@initialized = false
|
50
|
+
@translations = nil
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
def init_translations
|
57
|
+
load_translations
|
58
|
+
@initialized = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def translations
|
62
|
+
@translations ||= {}
|
63
|
+
end
|
64
|
+
|
65
|
+
# Looks up a translation from the translations hash. Returns nil if
|
66
|
+
# eiher key is nil, or locale, scope or key do not exist as a key in the
|
67
|
+
# nested translations hash. Splits keys or scopes containing dots
|
68
|
+
# into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
|
69
|
+
# <tt>%w(currency format)</tt>.
|
70
|
+
def lookup(locale, key, scope = [], options = {})
|
71
|
+
init_translations unless initialized?
|
72
|
+
keys = I18n.normalize_keys(locale, key, scope, options[:separator])
|
73
|
+
|
74
|
+
keys.inject(translations) do |result, key|
|
75
|
+
key = key.to_sym
|
76
|
+
return nil unless result.is_a?(Hash) && result.has_key?(key)
|
77
|
+
result = result[key]
|
78
|
+
result = resolve(locale, key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
|
79
|
+
result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
include Implementation
|
20
85
|
end
|
21
86
|
end
|
22
87
|
end
|
data/lib/i18n/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.4.0.beta1
|
9
|
+
version: 0.4.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Sven Fuchs
|
@@ -19,7 +18,7 @@ autorequire:
|
|
19
18
|
bindir: bin
|
20
19
|
cert_chain: []
|
21
20
|
|
22
|
-
date: 2010-05-
|
21
|
+
date: 2010-05-27 00:00:00 +02:00
|
23
22
|
default_executable:
|
24
23
|
dependencies: []
|
25
24
|
|