activesupport 2.2.3 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- data/CHANGELOG +128 -89
- data/lib/active_support.rb +31 -33
- data/lib/active_support/backtrace_cleaner.rb +72 -0
- data/lib/active_support/buffered_logger.rb +9 -7
- data/lib/active_support/cache.rb +13 -8
- data/lib/active_support/cache/drb_store.rb +2 -3
- data/lib/active_support/cache/mem_cache_store.rb +6 -1
- data/lib/active_support/cache/strategy/local_cache.rb +104 -0
- data/lib/active_support/callbacks.rb +20 -21
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/core_ext/array.rb +2 -0
- data/lib/active_support/core_ext/array/conversions.rb +26 -13
- data/lib/active_support/core_ext/array/wrapper.rb +24 -0
- data/lib/active_support/core_ext/benchmark.rb +13 -6
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -5
- data/lib/active_support/core_ext/class/attribute_accessors.rb +24 -24
- data/lib/active_support/core_ext/class/delegating_attributes.rb +20 -19
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +34 -34
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date_time/conversions.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +9 -0
- data/lib/active_support/core_ext/exception.rb +12 -8
- data/lib/active_support/core_ext/file/atomic.rb +2 -2
- data/lib/active_support/core_ext/hash/conversions.rb +32 -54
- data/lib/active_support/core_ext/hash/indifferent_access.rb +6 -0
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +8 -1
- data/lib/active_support/core_ext/logger.rb +8 -6
- data/lib/active_support/core_ext/module/aliasing.rb +3 -3
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +4 -4
- data/lib/active_support/core_ext/module/attribute_accessors.rb +24 -24
- data/lib/active_support/core_ext/module/delegation.rb +29 -3
- data/lib/active_support/core_ext/module/synchronization.rb +5 -5
- data/lib/active_support/core_ext/object/conversions.rb +2 -1
- data/lib/active_support/core_ext/object/misc.rb +16 -0
- data/lib/active_support/core_ext/range/conversions.rb +1 -1
- data/lib/active_support/core_ext/rexml.rb +29 -24
- data/lib/active_support/core_ext/string/inflections.rb +3 -3
- data/lib/active_support/core_ext/time/calculations.rb +1 -2
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/core_ext/try.rb +36 -0
- data/lib/active_support/dependencies.rb +18 -14
- data/lib/active_support/deprecation.rb +10 -57
- data/lib/active_support/duration.rb +3 -1
- data/lib/active_support/inflections.rb +1 -0
- data/lib/active_support/inflector.rb +16 -7
- data/lib/active_support/json/decoding.rb +21 -3
- data/lib/active_support/json/encoders/date.rb +1 -1
- data/lib/active_support/json/encoders/date_time.rb +1 -1
- data/lib/active_support/json/encoders/hash.rb +10 -11
- data/lib/active_support/json/encoders/time.rb +1 -1
- data/lib/active_support/json/encoding.rb +23 -29
- data/lib/active_support/locale/en.yml +3 -2
- data/lib/active_support/memoizable.rb +61 -43
- data/lib/active_support/message_encryptor.rb +70 -0
- data/lib/active_support/message_verifier.rb +46 -0
- data/lib/active_support/multibyte.rb +6 -30
- data/lib/active_support/multibyte/chars.rb +30 -9
- data/lib/active_support/multibyte/unicode_database.rb +4 -4
- data/lib/active_support/option_merger.rb +7 -1
- data/lib/active_support/ordered_hash.rb +75 -27
- data/lib/active_support/secure_random.rb +8 -6
- data/lib/active_support/test_case.rb +32 -17
- data/lib/active_support/testing/{core_ext/test/unit/assertions.rb → assertions.rb} +13 -20
- data/lib/active_support/testing/declarative.rb +21 -0
- data/lib/active_support/testing/deprecation.rb +55 -0
- data/lib/active_support/testing/performance.rb +1 -1
- data/lib/active_support/testing/setup_and_teardown.rb +57 -86
- data/lib/active_support/time_with_zone.rb +8 -6
- data/lib/active_support/values/time_zone.rb +1 -0
- data/lib/active_support/vendor.rb +6 -11
- data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +20 -0
- data/lib/active_support/vendor/i18n-0.1.3/README.textile +20 -0
- data/lib/active_support/vendor/i18n-0.1.3/Rakefile +5 -0
- data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +27 -0
- data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n.rb +42 -37
- data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n/backend/simple.rb +37 -39
- data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n/exceptions.rb +3 -3
- data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +5 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +100 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +125 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +1 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +3 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +568 -0
- data/lib/active_support/vendor/{memcache-client-1.5.1 → memcache-client-1.6.5}/memcache.rb +381 -295
- data/lib/active_support/version.rb +2 -2
- data/lib/active_support/xml_mini.rb +31 -0
- data/lib/active_support/xml_mini/libxml.rb +133 -0
- data/lib/active_support/xml_mini/nokogiri.rb +77 -0
- data/lib/active_support/xml_mini/rexml.rb +108 -0
- metadata +85 -14
- data/lib/active_support/multibyte/utils.rb +0 -61
- data/lib/active_support/testing/core_ext/test.rb +0 -6
- data/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +0 -1021
@@ -6,17 +6,12 @@ begin
|
|
6
6
|
rescue Gem::LoadError
|
7
7
|
$:.unshift "#{File.dirname(__FILE__)}/vendor/builder-2.1.2"
|
8
8
|
end
|
9
|
+
require 'builder'
|
9
10
|
|
10
11
|
begin
|
11
|
-
gem '
|
12
|
+
gem 'memcache-client', '>= 1.6.5'
|
12
13
|
rescue Gem::LoadError
|
13
|
-
$:.unshift "#{File.dirname(__FILE__)}/vendor/
|
14
|
-
end
|
15
|
-
|
16
|
-
begin
|
17
|
-
gem 'memcache-client', '>= 1.5.1'
|
18
|
-
rescue Gem::LoadError
|
19
|
-
$:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.5.1"
|
14
|
+
$:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.6.5"
|
20
15
|
end
|
21
16
|
|
22
17
|
begin
|
@@ -27,8 +22,8 @@ end
|
|
27
22
|
|
28
23
|
# TODO I18n gem has not been released yet
|
29
24
|
# begin
|
30
|
-
# gem 'i18n', '~> 0.
|
25
|
+
# gem 'i18n', '~> 0.1.3'
|
31
26
|
# rescue Gem::LoadError
|
32
|
-
$:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.
|
27
|
+
$:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.1.3/lib"
|
33
28
|
require 'i18n'
|
34
|
-
# end
|
29
|
+
# end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 The Ruby I18n team
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
h1. Ruby I18n gem
|
2
|
+
|
3
|
+
I18n and localization solution for Ruby.
|
4
|
+
|
5
|
+
For information please refer to http://rails-i18n.org
|
6
|
+
|
7
|
+
h2. Authors
|
8
|
+
|
9
|
+
* "Matt Aimonetti":http://railsontherun.com
|
10
|
+
* "Sven Fuchs":http://www.artweb-design.de
|
11
|
+
* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
|
12
|
+
* "Saimon Moore":http://saimonmoore.net
|
13
|
+
* "Stephan Soller":http://www.arkanis-development.de
|
14
|
+
|
15
|
+
h2. License
|
16
|
+
|
17
|
+
MIT License. See the included MIT-LICENCE file.
|
18
|
+
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "i18n"
|
3
|
+
s.version = "0.1.3"
|
4
|
+
s.date = "2009-01-09"
|
5
|
+
s.summary = "Internationalization support for Ruby"
|
6
|
+
s.email = "rails-i18n@googlegroups.com"
|
7
|
+
s.homepage = "http://rails-i18n.org"
|
8
|
+
s.description = "Add Internationalization support to your Ruby application."
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ['Sven Fuchs', 'Joshua Harvey', 'Matt Aimonetti', 'Stephan Soller', 'Saimon Moore']
|
11
|
+
s.files = [
|
12
|
+
'i18n.gemspec',
|
13
|
+
'lib/i18n/backend/simple.rb',
|
14
|
+
'lib/i18n/exceptions.rb',
|
15
|
+
'lib/i18n.rb',
|
16
|
+
'MIT-LICENSE',
|
17
|
+
'README.textile'
|
18
|
+
]
|
19
|
+
s.test_files = [
|
20
|
+
'test/all.rb',
|
21
|
+
'test/i18n_exceptions_test.rb',
|
22
|
+
'test/i18n_test.rb',
|
23
|
+
'test/locale/en.rb',
|
24
|
+
'test/locale/en.yml',
|
25
|
+
'test/simple_backend_test.rb'
|
26
|
+
]
|
27
|
+
end
|
@@ -2,39 +2,39 @@
|
|
2
2
|
# Sven Fuchs (http://www.artweb-design.de),
|
3
3
|
# Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
|
4
4
|
# Saimon Moore (http://saimonmoore.net),
|
5
|
-
# Stephan Soller (http://www.arkanis-development.de/)
|
5
|
+
# Stephan Soller (http://www.arkanis-development.de/)
|
6
6
|
# Copyright:: Copyright (c) 2008 The Ruby i18n Team
|
7
7
|
# License:: MIT
|
8
8
|
require 'i18n/backend/simple'
|
9
9
|
require 'i18n/exceptions'
|
10
10
|
|
11
|
-
module I18n
|
11
|
+
module I18n
|
12
12
|
@@backend = nil
|
13
13
|
@@load_path = nil
|
14
14
|
@@default_locale = :'en'
|
15
15
|
@@exception_handler = :default_exception_handler
|
16
|
-
|
16
|
+
|
17
17
|
class << self
|
18
18
|
# Returns the current backend. Defaults to +Backend::Simple+.
|
19
19
|
def backend
|
20
20
|
@@backend ||= Backend::Simple.new
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Sets the current backend. Used to set a custom backend.
|
24
|
-
def backend=(backend)
|
24
|
+
def backend=(backend)
|
25
25
|
@@backend = backend
|
26
26
|
end
|
27
|
-
|
28
|
-
# Returns the current default locale. Defaults to 'en'
|
27
|
+
|
28
|
+
# Returns the current default locale. Defaults to :'en'
|
29
29
|
def default_locale
|
30
|
-
@@default_locale
|
30
|
+
@@default_locale
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# Sets the current default locale. Used to set a custom default locale.
|
34
|
-
def default_locale=(locale)
|
35
|
-
@@default_locale = locale
|
34
|
+
def default_locale=(locale)
|
35
|
+
@@default_locale = locale
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
# Returns the current locale. Defaults to I18n.default_locale.
|
39
39
|
def locale
|
40
40
|
Thread.current[:locale] ||= default_locale
|
@@ -44,12 +44,17 @@ module I18n
|
|
44
44
|
def locale=(locale)
|
45
45
|
Thread.current[:locale] = locale
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
|
+
# Returns an array of locales for which translations are available
|
49
|
+
def available_locales
|
50
|
+
backend.available_locales
|
51
|
+
end
|
52
|
+
|
48
53
|
# Sets the exception handler.
|
49
54
|
def exception_handler=(exception_handler)
|
50
55
|
@@exception_handler = exception_handler
|
51
56
|
end
|
52
|
-
|
57
|
+
|
53
58
|
# Allow clients to register paths providing translation data sources. The
|
54
59
|
# backend defines acceptable sources.
|
55
60
|
#
|
@@ -74,25 +79,25 @@ module I18n
|
|
74
79
|
def reload!
|
75
80
|
backend.reload!
|
76
81
|
end
|
77
|
-
|
78
|
-
# Translates, pluralizes and interpolates a given key using a given locale,
|
82
|
+
|
83
|
+
# Translates, pluralizes and interpolates a given key using a given locale,
|
79
84
|
# scope, and default, as well as interpolation values.
|
80
85
|
#
|
81
86
|
# *LOOKUP*
|
82
87
|
#
|
83
|
-
# Translation data is organized as a nested hash using the upper-level keys
|
84
|
-
# as namespaces. <em>E.g.</em>, ActionView ships with the translation:
|
88
|
+
# Translation data is organized as a nested hash using the upper-level keys
|
89
|
+
# as namespaces. <em>E.g.</em>, ActionView ships with the translation:
|
85
90
|
# <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
|
86
|
-
#
|
87
|
-
# Translations can be looked up at any level of this hash using the key argument
|
88
|
-
# and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
|
91
|
+
#
|
92
|
+
# Translations can be looked up at any level of this hash using the key argument
|
93
|
+
# and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
|
89
94
|
# returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
|
90
|
-
#
|
91
|
-
# Key can be either a single key or a dot-separated key (both Strings and Symbols
|
95
|
+
#
|
96
|
+
# Key can be either a single key or a dot-separated key (both Strings and Symbols
|
92
97
|
# work). <em>E.g.</em>, the short format can be looked up using both:
|
93
98
|
# I18n.t 'date.formats.short'
|
94
99
|
# I18n.t :'date.formats.short'
|
95
|
-
#
|
100
|
+
#
|
96
101
|
# Scope can be either a single key, a dot-separated key or an array of keys
|
97
102
|
# or dot-separated keys. Keys and scopes can be combined freely. So these
|
98
103
|
# examples will all look up the same short date format:
|
@@ -105,9 +110,9 @@ module I18n
|
|
105
110
|
#
|
106
111
|
# Translations can contain interpolation variables which will be replaced by
|
107
112
|
# values passed to #translate as part of the options hash, with the keys matching
|
108
|
-
# the interpolation variable names.
|
113
|
+
# the interpolation variable names.
|
109
114
|
#
|
110
|
-
# <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
|
115
|
+
# <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
|
111
116
|
# value for the key +bar+ will be interpolated into the translation:
|
112
117
|
# I18n.t :foo, :bar => 'baz' # => 'foo baz'
|
113
118
|
#
|
@@ -116,7 +121,7 @@ module I18n
|
|
116
121
|
# Translation data can contain pluralized translations. Pluralized translations
|
117
122
|
# are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
|
118
123
|
#
|
119
|
-
# Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
|
124
|
+
# Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
|
120
125
|
# pluralization rules. Other algorithms can be supported by custom backends.
|
121
126
|
#
|
122
127
|
# This returns the singular version of a pluralized translation:
|
@@ -125,9 +130,9 @@ module I18n
|
|
125
130
|
# These both return the plural version of a pluralized translation:
|
126
131
|
# I18n.t :foo, :count => 0 # => 'Foos'
|
127
132
|
# I18n.t :foo, :count => 2 # => 'Foos'
|
128
|
-
#
|
129
|
-
# The <tt>:count</tt> option can be used both for pluralization and interpolation.
|
130
|
-
# <em>E.g.</em>, with the translation
|
133
|
+
#
|
134
|
+
# The <tt>:count</tt> option can be used both for pluralization and interpolation.
|
135
|
+
# <em>E.g.</em>, with the translation
|
131
136
|
# <tt>:foo => ['{{count}} foo', '{{count}} foos']</tt>, count will
|
132
137
|
# be interpolated to the pluralized translation:
|
133
138
|
# I18n.t :foo, :count => 1 # => '1 foo'
|
@@ -137,11 +142,11 @@ module I18n
|
|
137
142
|
# This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
|
138
143
|
# I18n.t :foo, :default => 'default'
|
139
144
|
#
|
140
|
-
# This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
|
145
|
+
# This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
|
141
146
|
# translation for <tt>:foo</tt> was found:
|
142
147
|
# I18n.t :foo, :default => :bar
|
143
148
|
#
|
144
|
-
# Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
|
149
|
+
# Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
|
145
150
|
# or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
|
146
151
|
# I18n.t :foo, :default => [:bar, 'default']
|
147
152
|
#
|
@@ -161,9 +166,9 @@ module I18n
|
|
161
166
|
rescue I18n::ArgumentError => e
|
162
167
|
raise e if options[:raise]
|
163
168
|
send(@@exception_handler, e, locale, key, options)
|
164
|
-
end
|
169
|
+
end
|
165
170
|
alias :t :translate
|
166
|
-
|
171
|
+
|
167
172
|
# Localizes certain objects, such as dates and numbers to local formatting.
|
168
173
|
def localize(object, options = {})
|
169
174
|
locale = options[:locale] || I18n.locale
|
@@ -171,7 +176,7 @@ module I18n
|
|
171
176
|
backend.localize(locale, object, format)
|
172
177
|
end
|
173
178
|
alias :l :localize
|
174
|
-
|
179
|
+
|
175
180
|
protected
|
176
181
|
# Handles exceptions raised in the backend. All exceptions except for
|
177
182
|
# MissingTranslationData exceptions are re-raised. When a MissingTranslationData
|
@@ -181,7 +186,7 @@ module I18n
|
|
181
186
|
return exception.message if MissingTranslationData === exception
|
182
187
|
raise exception
|
183
188
|
end
|
184
|
-
|
189
|
+
|
185
190
|
# Merges the given locale, key and scope into a single array of keys.
|
186
191
|
# Splits keys that contain dots into multiple keys. Makes sure all
|
187
192
|
# keys are Symbols.
|
@@ -191,4 +196,4 @@ module I18n
|
|
191
196
|
keys.flatten.map { |k| k.to_sym }
|
192
197
|
end
|
193
198
|
end
|
194
|
-
end
|
199
|
+
end
|
@@ -6,21 +6,21 @@ module I18n
|
|
6
6
|
INTERPOLATION_RESERVED_KEYS = %w(scope default)
|
7
7
|
MATCH = /(\\\\)?\{\{([^\}]+)\}\}/
|
8
8
|
|
9
|
-
# Accepts a list of paths to translation files. Loads translations from
|
9
|
+
# Accepts a list of paths to translation files. Loads translations from
|
10
10
|
# plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
|
11
11
|
# for details.
|
12
12
|
def load_translations(*filenames)
|
13
13
|
filenames.each { |filename| load_file(filename) }
|
14
14
|
end
|
15
|
-
|
16
|
-
# Stores translations for the given locale in memory.
|
15
|
+
|
16
|
+
# Stores translations for the given locale in memory.
|
17
17
|
# This uses a deep merge for the translations hash, so existing
|
18
18
|
# translations will be overwritten by new ones only at the deepest
|
19
19
|
# level of the hash.
|
20
20
|
def store_translations(locale, data)
|
21
21
|
merge_translations(locale, data)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def translate(locale, key, options = {})
|
25
25
|
raise InvalidLocale.new(locale) if locale.nil?
|
26
26
|
return key.map { |k| translate(locale, k, options) } if key.is_a? Array
|
@@ -41,13 +41,13 @@ module I18n
|
|
41
41
|
entry = interpolate(locale, entry, values)
|
42
42
|
entry
|
43
43
|
end
|
44
|
-
|
45
|
-
# Acts the same as +strftime+, but returns a localized version of the
|
46
|
-
# formatted date string. Takes a key from the date/time formats
|
47
|
-
# translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
|
44
|
+
|
45
|
+
# Acts the same as +strftime+, but returns a localized version of the
|
46
|
+
# formatted date string. Takes a key from the date/time formats
|
47
|
+
# translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
|
48
48
|
def localize(locale, object, format = :default)
|
49
49
|
raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
|
50
|
-
|
50
|
+
|
51
51
|
type = object.respond_to?(:sec) ? 'time' : 'date'
|
52
52
|
# TODO only translate these if format is a String?
|
53
53
|
formats = translate(locale, :"#{type}.formats")
|
@@ -57,18 +57,24 @@ module I18n
|
|
57
57
|
|
58
58
|
# TODO only translate these if the format string is actually present
|
59
59
|
# TODO check which format strings are present, then bulk translate then, then replace them
|
60
|
-
format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
|
60
|
+
format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
|
61
61
|
format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
|
62
62
|
format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
|
63
63
|
format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
|
64
64
|
format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
|
65
65
|
object.strftime(format)
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
def initialized?
|
69
69
|
@initialized ||= false
|
70
70
|
end
|
71
71
|
|
72
|
+
# Returns an array of locales for which translations are available
|
73
|
+
def available_locales
|
74
|
+
init_translations unless initialized?
|
75
|
+
translations.keys
|
76
|
+
end
|
77
|
+
|
72
78
|
def reload!
|
73
79
|
@initialized = false
|
74
80
|
@translations = nil
|
@@ -76,15 +82,15 @@ module I18n
|
|
76
82
|
|
77
83
|
protected
|
78
84
|
def init_translations
|
79
|
-
load_translations(*I18n.load_path)
|
85
|
+
load_translations(*I18n.load_path.flatten)
|
80
86
|
@initialized = true
|
81
87
|
end
|
82
|
-
|
88
|
+
|
83
89
|
def translations
|
84
90
|
@translations ||= {}
|
85
91
|
end
|
86
|
-
|
87
|
-
# Looks up a translation from the translations hash. Returns nil if
|
92
|
+
|
93
|
+
# Looks up a translation from the translations hash. Returns nil if
|
88
94
|
# eiher key is nil, or locale, scope or key do not exist as a key in the
|
89
95
|
# nested translations hash. Splits keys or scopes containing dots
|
90
96
|
# into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
|
@@ -101,19 +107,19 @@ module I18n
|
|
101
107
|
end
|
102
108
|
end
|
103
109
|
end
|
104
|
-
|
105
|
-
# Evaluates a default translation.
|
110
|
+
|
111
|
+
# Evaluates a default translation.
|
106
112
|
# If the given default is a String it is used literally. If it is a Symbol
|
107
113
|
# it will be translated with the given options. If it is an Array the first
|
108
114
|
# translation yielded will be returned.
|
109
|
-
#
|
110
|
-
# <em>I.e.</em>, <tt>default(locale, [:foo, 'default'])</tt> will return +default+ if
|
115
|
+
#
|
116
|
+
# <em>I.e.</em>, <tt>default(locale, [:foo, 'default'])</tt> will return +default+ if
|
111
117
|
# <tt>translate(locale, :foo)</tt> does not yield a result.
|
112
118
|
def default(locale, default, options = {})
|
113
119
|
case default
|
114
120
|
when String then default
|
115
121
|
when Symbol then translate locale, default, options
|
116
|
-
when Array then default.each do |obj|
|
122
|
+
when Array then default.each do |obj|
|
117
123
|
result = default(locale, obj, options.dup) and return result
|
118
124
|
end and nil
|
119
125
|
end
|
@@ -135,22 +141,17 @@ module I18n
|
|
135
141
|
end
|
136
142
|
|
137
143
|
# Interpolates values into a given string.
|
138
|
-
#
|
139
|
-
# interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
|
144
|
+
#
|
145
|
+
# interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
|
140
146
|
# # => "file test.txt opened by {{user}}"
|
141
|
-
#
|
147
|
+
#
|
142
148
|
# Note that you have to double escape the <tt>\\</tt> when you want to escape
|
143
149
|
# the <tt>{{...}}</tt> key in a string (once for the string and once for the
|
144
150
|
# interpolation).
|
145
151
|
def interpolate(locale, string, values = {})
|
146
152
|
return string unless string.is_a?(String)
|
147
153
|
|
148
|
-
|
149
|
-
original_encoding = string.encoding
|
150
|
-
string.force_encoding(Encoding::BINARY)
|
151
|
-
end
|
152
|
-
|
153
|
-
result = string.gsub(MATCH) do
|
154
|
+
string.gsub(MATCH) do
|
154
155
|
escaped, pattern, key = $1, $2, $2.to_sym
|
155
156
|
|
156
157
|
if escaped
|
@@ -163,12 +164,9 @@ module I18n
|
|
163
164
|
values[key].to_s
|
164
165
|
end
|
165
166
|
end
|
166
|
-
|
167
|
-
result.force_encoding(original_encoding) if original_encoding
|
168
|
-
result
|
169
167
|
end
|
170
|
-
|
171
|
-
# Loads a single translations file by delegating to #load_rb or
|
168
|
+
|
169
|
+
# Loads a single translations file by delegating to #load_rb or
|
172
170
|
# #load_yml depending on the file extension and directly merges the
|
173
171
|
# data to the existing translations. Raises I18n::UnknownFileType
|
174
172
|
# for all other file extensions.
|
@@ -178,19 +176,19 @@ module I18n
|
|
178
176
|
data = send :"load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
|
179
177
|
data.each { |locale, d| merge_translations(locale, d) }
|
180
178
|
end
|
181
|
-
|
179
|
+
|
182
180
|
# Loads a plain Ruby translations file. eval'ing the file must yield
|
183
181
|
# a Hash containing translation data with locales as toplevel keys.
|
184
182
|
def load_rb(filename)
|
185
183
|
eval(IO.read(filename), binding, filename)
|
186
184
|
end
|
187
|
-
|
188
|
-
# Loads a YAML translations file. The data must have locales as
|
185
|
+
|
186
|
+
# Loads a YAML translations file. The data must have locales as
|
189
187
|
# toplevel keys.
|
190
188
|
def load_yml(filename)
|
191
189
|
YAML::load(IO.read(filename))
|
192
190
|
end
|
193
|
-
|
191
|
+
|
194
192
|
# Deep merges the given translations hash with the existing translations
|
195
193
|
# for the given locale
|
196
194
|
def merge_translations(locale, data)
|
@@ -202,7 +200,7 @@ module I18n
|
|
202
200
|
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
203
201
|
translations[locale].merge!(data, &merger)
|
204
202
|
end
|
205
|
-
|
203
|
+
|
206
204
|
# Return a new hash with all keys and nested keys converted to symbols.
|
207
205
|
def deep_symbolize_keys(hash)
|
208
206
|
hash.inject({}) { |result, (key, value)|
|