i18n-js 3.0.0.rc7 → 3.0.0.rc8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +70 -0
- data/Rakefile +2 -1
- data/app/assets/javascripts/i18n.js +37 -6
- data/app/assets/javascripts/i18n/filtered.js.erb +19 -1
- data/lib/i18n/js.rb +25 -0
- data/lib/i18n/js/engine.rb +0 -1
- data/lib/i18n/js/fallback_locales.rb +81 -0
- data/lib/i18n/js/version.rb +1 -1
- data/package.json +1 -1
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +4 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +6 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +4 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +4 -0
- data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +4 -0
- data/spec/fixtures/locales.yml +4 -0
- data/spec/i18n_js_fallback_locales_spec.rb +94 -0
- data/spec/i18n_js_spec.rb +67 -2
- data/spec/js/interpolation.spec.js +14 -1
- data/spec/js/localization.spec.js +7 -0
- data/spec/js/pluralization.spec.js +2 -1
- data/spec/js/translations.js +2 -0
- data/spec/spec_helper.rb +9 -0
- metadata +16 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5f7d877f8e94243760d5e3c4c3bbe232badc99d
|
4
|
+
data.tar.gz: 0d2cf27dc10c17acc846c457ec48573ae9832413
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ebf38bdbc12665767e0c7c3806fd02221204b26e8b1f82dda78c3f07534ec5cedd18b4b6bc133c2820effc6ddb0f3c6902318a76b78563ceb232e99272213b8
|
7
|
+
data.tar.gz: c505d9671c59b80c51c28a033b03c8cac3bdc4174621789f7f9e48e5257324c37803f4e1f084cc337c3512894c193bbbf8a820e78c6495f570872dee4ff50f28
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,33 @@
|
|
3
3
|
|
4
4
|
### enhancements
|
5
5
|
|
6
|
+
### bug fixes
|
7
|
+
|
8
|
+
|
9
|
+
## 3.0.0.rc8
|
10
|
+
|
11
|
+
### enhancements
|
12
|
+
|
13
|
+
- Add support for loading via AMD and CommonJS module loaders ([#266](https://github.com/fnando/i18n-js/pull/266))
|
14
|
+
- Add `I18n.nullPlaceholder`
|
15
|
+
Defaults to I18n.missingPlaceholder (`[missing {{name}} value]`)
|
16
|
+
Set to `function() {return "";}` to match Ruby `I18n.t("name: %{name}", name: nil)`
|
17
|
+
- For date formatting, you can now also add placeholders to the date format, see README for detail
|
18
|
+
- Add fallbacks option to `i18n-js.yml`, defaults to `true`
|
19
|
+
|
20
|
+
### bug fixes
|
21
|
+
|
22
|
+
- Fix factory initialization so that the Node/CommonJS branch only gets executed if the environment is Node/CommonJS
|
23
|
+
(it currently will execute if module is defined in the global scope, which occurs with QUnit, for example)
|
24
|
+
- Fix pluralization rules selection for negative `count` (e.g. `-1` was lead to use `one` for pluralization) ([#268](https://github.com/fnando/i18n-js/pull/268))
|
25
|
+
- Remove check for `Rails.configuration.assets.compile` before telling Sprockets the dependency of translations JS file
|
26
|
+
This might be the reason of many "cache not expired" issues
|
27
|
+
Discovered/reported in #277
|
28
|
+
|
29
|
+
## 3.0.0.rc7
|
30
|
+
|
31
|
+
### enhancements
|
32
|
+
|
6
33
|
- The Rails Engine initializer is now named as `i18n-js.register_preprocessor` (https://github.com/fnando/i18n-js/pull/261)
|
7
34
|
- Rename `I18n::JS.config_file` to `I18n::JS.config_file_path` and make it configurable
|
8
35
|
Expected a `String`, default is still `config/i18n-js.yml`
|
data/README.md
CHANGED
@@ -121,6 +121,65 @@ translations:
|
|
121
121
|
|
122
122
|
To find more examples on how to use the configuration file please refer to the tests.
|
123
123
|
|
124
|
+
##### Fallbacks
|
125
|
+
|
126
|
+
If you specify the `fallbacks` option, you will be able to fill missing translations with those inside fallback locale(s).
|
127
|
+
Default value is `true`.
|
128
|
+
|
129
|
+
Examples:
|
130
|
+
```yaml
|
131
|
+
fallbacks: true
|
132
|
+
|
133
|
+
translations:
|
134
|
+
- file: "public/javascripts/i18n/%{locale}.js"
|
135
|
+
only: '*'
|
136
|
+
```
|
137
|
+
This will enable merging fallbacks into each file. (set to `false` to disable).
|
138
|
+
If you use `I18n` with fallbacks, the fallbacks defined there will be used.
|
139
|
+
Otherwise `I18n.default_locale` will be used.
|
140
|
+
|
141
|
+
```yaml
|
142
|
+
fallbacks: :de
|
143
|
+
|
144
|
+
translations:
|
145
|
+
- file: "public/javascripts/i18n/%{locale}.js"
|
146
|
+
only: '*'
|
147
|
+
```
|
148
|
+
Here, the specified locale `:de` will be used as fallback for all locales.
|
149
|
+
|
150
|
+
```yaml
|
151
|
+
fallbacks:
|
152
|
+
fr: ["de", "en"]
|
153
|
+
de: "en"
|
154
|
+
|
155
|
+
translations:
|
156
|
+
- file: "public/javascripts/i18n/%{locale}.js"
|
157
|
+
only: '*'
|
158
|
+
```
|
159
|
+
Fallbacks defined will be used, if not defined (e.g. `:pl`) `I18n.fallbacks` or `I18n.default_locale` will be used.
|
160
|
+
|
161
|
+
```yaml
|
162
|
+
fallbacks: :default_locale
|
163
|
+
|
164
|
+
translations:
|
165
|
+
- file: "public/javascripts/i18n/%{locale}.js"
|
166
|
+
only: '*'
|
167
|
+
```
|
168
|
+
Setting the option to `:default_locale` will enforce the fallback to use the `I18n.default_locale`, ignoring `I18n.fallbacks`.
|
169
|
+
|
170
|
+
Examples:
|
171
|
+
```yaml
|
172
|
+
fallbacks: false
|
173
|
+
|
174
|
+
translations:
|
175
|
+
- file: "public/javascripts/i18n/%{locale}.js"
|
176
|
+
only: '*'
|
177
|
+
```
|
178
|
+
You must disable this feature by setting the option to `false`.
|
179
|
+
|
180
|
+
To find more examples on how to use the configuration file please refer to the tests.
|
181
|
+
|
182
|
+
|
124
183
|
#### Vanilla JavaScript
|
125
184
|
|
126
185
|
Just add the `i18n.js` file to your page. You'll have to build the translations object
|
@@ -320,6 +379,17 @@ The `toHumanSize` function accepts the following options:
|
|
320
379
|
I18n.l("date.formats.short", "09/18/2009"); // mm/dd/yyyy
|
321
380
|
I18n.l("date.formats.short", (new Date())); // Date object
|
322
381
|
|
382
|
+
You can also add placeholders to the date format:
|
383
|
+
|
384
|
+
I18n.translations["en"] = {
|
385
|
+
date: {
|
386
|
+
formats: {
|
387
|
+
ordinal_day: "%B %{day}"
|
388
|
+
}
|
389
|
+
}
|
390
|
+
}
|
391
|
+
I18n.l("date.formats.ordinal_day", "2009-09-18", { day: '18th' }); // Sep 18th
|
392
|
+
|
323
393
|
If you prefer, you can use the `I18n.strftime` function to format dates.
|
324
394
|
|
325
395
|
var date = new Date();
|
data/Rakefile
CHANGED
@@ -11,9 +11,26 @@
|
|
11
11
|
//
|
12
12
|
// See tests for specific formatting like numbers and dates.
|
13
13
|
//
|
14
|
-
|
14
|
+
|
15
|
+
;(function(factory) {
|
16
|
+
if (typeof module !== 'undefined' && module.exports) {
|
17
|
+
// Node/CommonJS
|
18
|
+
module.exports = factory(this);
|
19
|
+
|
20
|
+
} else if (typeof define === 'function' && define.amd) {
|
21
|
+
// AMD
|
22
|
+
define((function(global){ return function(){ factory(global); }})(this));
|
23
|
+
|
24
|
+
} else {
|
25
|
+
// Browser globals
|
26
|
+
this.I18n = factory(this);
|
27
|
+
}
|
28
|
+
}(function(global) {
|
15
29
|
"use strict";
|
16
30
|
|
31
|
+
// Use previously defined object if exists in current scope
|
32
|
+
var I18n = global && global.I18n || {};
|
33
|
+
|
17
34
|
// Just cache the Array#slice function.
|
18
35
|
var slice = Array.prototype.slice;
|
19
36
|
|
@@ -407,6 +424,8 @@
|
|
407
424
|
|
408
425
|
if (this.isSet(options[name])) {
|
409
426
|
value = options[name].toString().replace(/\$/gm, "_#$#_");
|
427
|
+
} else if (name in options) {
|
428
|
+
value = this.nullPlaceholder(placeholder, message);
|
410
429
|
} else {
|
411
430
|
value = this.missingPlaceholder(placeholder, message);
|
412
431
|
}
|
@@ -436,7 +455,7 @@
|
|
436
455
|
}
|
437
456
|
|
438
457
|
pluralizer = this.pluralization.get(options.locale);
|
439
|
-
keys = pluralizer(
|
458
|
+
keys = pluralizer(count);
|
440
459
|
|
441
460
|
while (keys.length) {
|
442
461
|
key = keys.shift();
|
@@ -467,6 +486,10 @@
|
|
467
486
|
return "[missing " + placeholder + " value]";
|
468
487
|
};
|
469
488
|
|
489
|
+
I18n.nullPlaceholder = function() {
|
490
|
+
return I18n.missingPlaceholder.apply(I18n, arguments);
|
491
|
+
};
|
492
|
+
|
470
493
|
// Format number using localization rules.
|
471
494
|
// The options will be retrieved from the `number.format` scope.
|
472
495
|
// If this isn't present, then the following options will be used:
|
@@ -557,7 +580,9 @@
|
|
557
580
|
//
|
558
581
|
// It will default to the value's `toString` function.
|
559
582
|
//
|
560
|
-
I18n.localize = function(scope, value) {
|
583
|
+
I18n.localize = function(scope, value, options) {
|
584
|
+
options || (options = {});
|
585
|
+
|
561
586
|
switch (scope) {
|
562
587
|
case "currency":
|
563
588
|
return this.toCurrency(value);
|
@@ -567,11 +592,15 @@
|
|
567
592
|
case "percentage":
|
568
593
|
return this.toPercentage(value);
|
569
594
|
default:
|
595
|
+
var localizedValue;
|
596
|
+
|
570
597
|
if (scope.match(/^(date|time)/)) {
|
571
|
-
|
598
|
+
localizedValue = this.toTime(scope, value);
|
572
599
|
} else {
|
573
|
-
|
600
|
+
localizedValue = value.toString();
|
574
601
|
}
|
602
|
+
|
603
|
+
return this.interpolate(localizedValue, options);
|
575
604
|
}
|
576
605
|
};
|
577
606
|
|
@@ -797,4 +826,6 @@
|
|
797
826
|
I18n.t = I18n.translate;
|
798
827
|
I18n.l = I18n.localize;
|
799
828
|
I18n.p = I18n.pluralize;
|
800
|
-
|
829
|
+
|
830
|
+
return I18n;
|
831
|
+
}));
|
@@ -1,2 +1,20 @@
|
|
1
1
|
<%# encoding: utf-8 %>
|
2
|
-
|
2
|
+
|
3
|
+
;(function(factory) {
|
4
|
+
if (typeof module !== 'undefined') {
|
5
|
+
// Node/CommonJS
|
6
|
+
factory(require('i18n'));
|
7
|
+
|
8
|
+
} else if (typeof define === 'function' && define.amd) {
|
9
|
+
// AMD
|
10
|
+
define(['i18n'], factory);
|
11
|
+
|
12
|
+
} else {
|
13
|
+
// Browser globals
|
14
|
+
factory(this.I18n);
|
15
|
+
}
|
16
|
+
}(function(I18n) {
|
17
|
+
"use strict";
|
18
|
+
|
19
|
+
I18n.translations = <%= I18n::JS.filtered_translations.to_json %>;
|
20
|
+
}));
|
data/lib/i18n/js.rb
CHANGED
@@ -6,6 +6,7 @@ require "i18n/js/utils"
|
|
6
6
|
module I18n
|
7
7
|
module JS
|
8
8
|
require "i18n/js/dependencies"
|
9
|
+
require "i18n/js/fallback_locales"
|
9
10
|
if JS::Dependencies.rails?
|
10
11
|
require "i18n/js/middleware"
|
11
12
|
require "i18n/js/engine"
|
@@ -37,6 +38,8 @@ module I18n
|
|
37
38
|
I18n.available_locales.each_with_object({}) do |locale, segments|
|
38
39
|
scope = [scope] unless scope.respond_to?(:each)
|
39
40
|
result = scoped_translations(scope.collect{|s| "#{locale}.#{s}"})
|
41
|
+
merge_with_fallbacks!(result, locale, scope) if use_fallbacks?
|
42
|
+
|
40
43
|
next if result.empty?
|
41
44
|
|
42
45
|
segment_name = ::I18n.interpolate(pattern,{:locale => locale})
|
@@ -145,6 +148,28 @@ module I18n
|
|
145
148
|
end
|
146
149
|
end
|
147
150
|
|
151
|
+
def self.use_fallbacks?
|
152
|
+
fallbacks != false
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.fallbacks
|
156
|
+
config.fetch(:fallbacks) do
|
157
|
+
# default value
|
158
|
+
true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# deep_merge! given result with result for fallback locale
|
163
|
+
def self.merge_with_fallbacks!(result, locale, scope)
|
164
|
+
result[locale] ||= {}
|
165
|
+
fallback_locales = FallbackLocales.new(fallbacks, locale)
|
166
|
+
|
167
|
+
fallback_locales.each do |fallback_locale|
|
168
|
+
fallback_result = scoped_translations(scope.collect{|s| "#{fallback_locale}.#{s}"}) # NOTE: Duplicated code here
|
169
|
+
result[locale] = Utils.deep_merge(fallback_result[fallback_locale], result[locale])
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
148
173
|
|
149
174
|
### Export i18n.js
|
150
175
|
begin
|
data/lib/i18n/js/engine.rb
CHANGED
@@ -6,7 +6,6 @@ module I18n
|
|
6
6
|
initializer "i18n-js.register_preprocessor", :after => "sprockets.environment" do
|
7
7
|
next unless JS::Dependencies.using_asset_pipeline?
|
8
8
|
next unless JS::Dependencies.sprockets_supports_register_preprocessor?
|
9
|
-
next unless Rails.configuration.assets.compile
|
10
9
|
|
11
10
|
Rails.application.assets.register_preprocessor "application/javascript", :"i18n-js_dependencies" do |context, source|
|
12
11
|
if context.logical_path == "i18n/filtered"
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module I18n
|
2
|
+
module JS
|
3
|
+
class FallbackLocales
|
4
|
+
attr_reader :fallbacks, :locale
|
5
|
+
|
6
|
+
def initialize(fallbacks, locale)
|
7
|
+
@fallbacks = fallbacks
|
8
|
+
@locale = locale
|
9
|
+
end
|
10
|
+
|
11
|
+
def each
|
12
|
+
locales.each { |locale| yield(locale) }
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array<String, Symbol>]
|
16
|
+
# An Array of locales to use as fallbacks for given locale.
|
17
|
+
def locales
|
18
|
+
locales = case fallbacks
|
19
|
+
when true
|
20
|
+
default_fallbacks
|
21
|
+
when :default_locale
|
22
|
+
[::I18n.default_locale]
|
23
|
+
when Symbol, String
|
24
|
+
[fallbacks.to_sym]
|
25
|
+
when Array
|
26
|
+
ensure_valid_fallbacks_as_array!
|
27
|
+
fallbacks
|
28
|
+
when Hash
|
29
|
+
Array(fallbacks[locale] || default_fallbacks)
|
30
|
+
else
|
31
|
+
fail ArgumentError, "fallbacks must be: true, :default_locale an Array or a Hash - given: #{fallbacks}"
|
32
|
+
end
|
33
|
+
|
34
|
+
locales.map! { |locale| locale.to_sym }
|
35
|
+
ensure_valid_locales!(locales)
|
36
|
+
locales
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @return [Array<String, Symbol>] An Array of locales.
|
42
|
+
def default_fallbacks
|
43
|
+
if using_i18n_fallbacks_module?
|
44
|
+
I18n.fallbacks[locale]
|
45
|
+
else
|
46
|
+
[::I18n.default_locale]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return
|
51
|
+
# true if we can safely use I18n.fallbacks, false otherwise.
|
52
|
+
#
|
53
|
+
# @note
|
54
|
+
# We should implement this as `I18n.respond_to?(:fallbacks)`, but
|
55
|
+
# once I18n::Backend::Fallbacks is included, I18n will _always_
|
56
|
+
# respond to :fallbacks. Even if we switch the backend to one
|
57
|
+
# without fallbacks!
|
58
|
+
#
|
59
|
+
# Maybe this should be fixed within I18n.
|
60
|
+
def using_i18n_fallbacks_module?
|
61
|
+
I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
|
62
|
+
end
|
63
|
+
|
64
|
+
def ensure_valid_fallbacks_as_array!
|
65
|
+
return if fallbacks.all? { |e| e.is_a?(String) || e.is_a?(Symbol) }
|
66
|
+
|
67
|
+
fail ArgumentError, "If fallbacks is passed as Array, it must ony include Strings or Symbols. Given: #{fallbacks}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Ensures that only valid locales are returned.
|
71
|
+
#
|
72
|
+
# @note
|
73
|
+
# This ignores option `I18n.enforce_available_locales`
|
74
|
+
def ensure_valid_locales!(locales)
|
75
|
+
if locales.any? { |locale| !::I18n.available_locales.include?(locale) }
|
76
|
+
fail ArgumentError, "Valid locales: #{::I18n.available_locales} - Given Locales: #{locales}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/i18n/js/version.rb
CHANGED
data/package.json
CHANGED
data/spec/fixtures/locales.yml
CHANGED
@@ -0,0 +1,94 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe I18n::JS::FallbackLocales do
|
4
|
+
let(:locale) { :fr }
|
5
|
+
let(:default_locale) { :en }
|
6
|
+
|
7
|
+
describe "#locales" do
|
8
|
+
let(:fallbacks_locales) { described_class.new(fallbacks, locale) }
|
9
|
+
subject { fallbacks_locales.locales }
|
10
|
+
|
11
|
+
let(:fetching_locales) { proc do fallbacks_locales.locales end }
|
12
|
+
|
13
|
+
context "when given true as fallbacks" do
|
14
|
+
let(:fallbacks) { true }
|
15
|
+
it { should eq([default_locale]) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when given false as fallbacks" do
|
19
|
+
let(:fallbacks) { false }
|
20
|
+
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when given a valid locale as fallbacks" do
|
24
|
+
let(:fallbacks) { :de }
|
25
|
+
it { should eq([:de]) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when given a valid Array as fallbacks" do
|
29
|
+
let(:fallbacks) { [:de, :en] }
|
30
|
+
it { should eq([:de, :en]) }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when given a valid Hash with current locale as key as fallbacks" do
|
34
|
+
let(:fallbacks) do { :fr => [:de, :en] } end
|
35
|
+
it { should eq([:de, :en]) }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when given a valid Hash without current locale as key as fallbacks" do
|
39
|
+
let(:fallbacks) do { :de => [:fr, :en] } end
|
40
|
+
it { should eq([default_locale]) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when given a invalid locale as fallbacks" do
|
44
|
+
let(:fallbacks) { :invalid_locale }
|
45
|
+
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when given a invalid type as fallbacks" do
|
49
|
+
let(:fallbacks) { 42 }
|
50
|
+
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when given an invalid Array as fallbacks" do
|
54
|
+
let(:fallbacks) { [:de, :en, :invalid_locale] }
|
55
|
+
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when given a invalid Hash as fallbacks" do
|
59
|
+
let(:fallbacks) do { :fr => [:de, :en, :invalid_locale] } end
|
60
|
+
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
61
|
+
end
|
62
|
+
|
63
|
+
# I18n::Backend::Fallbacks
|
64
|
+
context "when I18n::Backend::Fallbacks is used" do
|
65
|
+
let(:backend_with_fallbacks) { backend_class_with_fallbacks.new }
|
66
|
+
|
67
|
+
before do
|
68
|
+
I18n.backend = backend_with_fallbacks
|
69
|
+
I18n.fallbacks[:fr] = [:de, :en]
|
70
|
+
end
|
71
|
+
after { I18n.backend = I18n::Backend::Simple.new }
|
72
|
+
|
73
|
+
context "given true as fallbacks" do
|
74
|
+
let(:fallbacks) { true }
|
75
|
+
it { should eq([:de, :en]) }
|
76
|
+
end
|
77
|
+
|
78
|
+
context "given :default_locale as fallbacks" do
|
79
|
+
let(:fallbacks) { :default_locale }
|
80
|
+
it { should eq([:en]) }
|
81
|
+
end
|
82
|
+
|
83
|
+
context "given a Hash with current locale as fallbacks" do
|
84
|
+
let(:fallbacks) do { :fr => [:en] } end
|
85
|
+
it { should eq([:en]) }
|
86
|
+
end
|
87
|
+
|
88
|
+
context "given a Hash without current locale as fallbacks" do
|
89
|
+
let(:fallbacks) do { :de => [:en] } end
|
90
|
+
it { should eq([:de, :en]) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/spec/i18n_js_spec.rb
CHANGED
@@ -73,10 +73,13 @@ describe I18n::JS do
|
|
73
73
|
|
74
74
|
set_config "multiple_conditions_per_locale.yml"
|
75
75
|
|
76
|
+
expected_locales = %w(en fr)
|
77
|
+
|
76
78
|
result = I18n::JS.translation_segments
|
77
|
-
|
79
|
+
expected_files = expected_locales.map { |locale| "tmp/i18n-js/bits.#{locale}.js" }
|
80
|
+
result.keys.should eql(expected_files)
|
78
81
|
|
79
|
-
|
82
|
+
expected_locales.each do |lang|
|
80
83
|
result["tmp/i18n-js/bits.#{lang}.js"].keys.should eql([lang.to_sym])
|
81
84
|
result["tmp/i18n-js/bits.#{lang}.js"][lang.to_sym].keys.sort.should eql([:date, :number])
|
82
85
|
end
|
@@ -129,6 +132,68 @@ describe I18n::JS do
|
|
129
132
|
end
|
130
133
|
end
|
131
134
|
|
135
|
+
context "fallbacks" do
|
136
|
+
it "exports without fallback when disabled" do
|
137
|
+
set_config "js_file_per_locale_without_fallbacks.yml"
|
138
|
+
|
139
|
+
result = I18n::JS.translation_segments
|
140
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql(nil)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "exports with default_locale as fallback when enabled" do
|
144
|
+
set_config "js_file_per_locale_with_fallbacks_enabled.yml"
|
145
|
+
|
146
|
+
result = I18n::JS.translation_segments
|
147
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql("Success")
|
148
|
+
end
|
149
|
+
|
150
|
+
it "exports with default_locale as fallback when enabled with :default_locale" do
|
151
|
+
set_config "js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml"
|
152
|
+
|
153
|
+
result = I18n::JS.translation_segments
|
154
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql("Success")
|
155
|
+
end
|
156
|
+
|
157
|
+
it "exports with given locale as fallback" do
|
158
|
+
set_config "js_file_per_locale_with_fallbacks_as_locale.yml"
|
159
|
+
|
160
|
+
result = I18n::JS.translation_segments
|
161
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql("Erfolg")
|
162
|
+
end
|
163
|
+
|
164
|
+
context "with I18n::Fallbacks enabled" do
|
165
|
+
let(:backend_with_fallbacks) { backend_class_with_fallbacks.new }
|
166
|
+
let!(:old_backebad) { I18n.backend }
|
167
|
+
|
168
|
+
before do
|
169
|
+
I18n.backend = backend_with_fallbacks
|
170
|
+
I18n.fallbacks[:fr] = [:de, :en]
|
171
|
+
end
|
172
|
+
after { I18n.backend = old_backebad }
|
173
|
+
|
174
|
+
it "exports with defined locale as fallback when enabled" do
|
175
|
+
set_config "js_file_per_locale_with_fallbacks_enabled.yml"
|
176
|
+
|
177
|
+
result = I18n::JS.translation_segments
|
178
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql("Erfolg")
|
179
|
+
end
|
180
|
+
|
181
|
+
it "exports with defined locale as fallback when enabled with :default_locale" do
|
182
|
+
set_config "js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml"
|
183
|
+
|
184
|
+
result = I18n::JS.translation_segments
|
185
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql("Success")
|
186
|
+
end
|
187
|
+
|
188
|
+
it "exports with Fallbacks as Hash" do
|
189
|
+
set_config "js_file_per_locale_with_fallbacks_as_hash.yml"
|
190
|
+
|
191
|
+
result = I18n::JS.translation_segments
|
192
|
+
result["tmp/i18n-js/fr.js"][:fr][:fallback_test].should eql("Erfolg")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
132
197
|
context "I18n.available_locales" do
|
133
198
|
context "when I18n.available_locales is not set" do
|
134
199
|
it "should allow all locales" do
|
@@ -29,5 +29,18 @@ describe("Interpolation", function(){
|
|
29
29
|
it("outputs missing placeholder message if interpolation value is missing", function(){
|
30
30
|
actual = I18n.t("greetings.name");
|
31
31
|
expect(actual).toEqual("Hello [missing {{name}} value]!");
|
32
|
-
})
|
32
|
+
});
|
33
|
+
|
34
|
+
it("outputs missing placeholder message if interpolation value is null", function(){
|
35
|
+
actual = I18n.t("greetings.name", {name: null});
|
36
|
+
expect(actual).toEqual("Hello [missing {{name}} value]!");
|
37
|
+
});
|
38
|
+
|
39
|
+
it("allows overriding the null placeholder message", function(){
|
40
|
+
var orig = I18n.nullPlaceholder;
|
41
|
+
I18n.nullPlaceholder = function() {return "";}
|
42
|
+
actual = I18n.t("greetings.name", {name: null});
|
43
|
+
expect(actual).toEqual("Hello !");
|
44
|
+
I18n.nullPlaceholder = orig;
|
45
|
+
});
|
33
46
|
});
|
@@ -34,6 +34,13 @@ describe("Localization", function(){
|
|
34
34
|
expect(I18n.l("time.formats.long", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
35
35
|
});
|
36
36
|
|
37
|
+
it("localizes date/time strings with placeholders", function(){
|
38
|
+
I18n.locale = "pt-BR";
|
39
|
+
|
40
|
+
expect(I18n.l("date.formats.short_with_placeholders", "2009-01-07", { p1: "!", p2: "?" })).toEqual("07 de Janeiro ! ?");
|
41
|
+
expect(I18n.l("time.formats.short_with_placeholders", "2009-01-07 09:12:35", { p1: "!" })).toEqual("07/01, 09:12 h !");
|
42
|
+
});
|
43
|
+
|
37
44
|
it("localizes percentage", function(){
|
38
45
|
I18n.locale = "pt-BR";
|
39
46
|
expect(I18n.l("percentage", 123.45)).toEqual("123,45%");
|
@@ -32,7 +32,7 @@ describe("Pluralization", function(){
|
|
32
32
|
});
|
33
33
|
|
34
34
|
it("pluralizes using negative values", function(){
|
35
|
-
expect(I18n.p(-1, "inbox")).toEqual("You have -1
|
35
|
+
expect(I18n.p(-1, "inbox")).toEqual("You have -1 messages");
|
36
36
|
expect(I18n.p(-5, "inbox")).toEqual("You have -5 messages");
|
37
37
|
});
|
38
38
|
|
@@ -76,6 +76,7 @@ describe("Pluralization", function(){
|
|
76
76
|
|
77
77
|
expect(I18n.p(0, "things")).toEqual("No things");
|
78
78
|
expect(I18n.p(4, "things")).toEqual("A few things");
|
79
|
+
expect(I18n.p(-4, "things")).toEqual("-4 things");
|
79
80
|
expect(I18n.p(10, "things")).toEqual("10 things");
|
80
81
|
});
|
81
82
|
|
data/spec/js/translations.js
CHANGED
@@ -88,6 +88,7 @@ var DEBUG = false;
|
|
88
88
|
"default": "%d/%m/%Y"
|
89
89
|
, "short": "%d de %B"
|
90
90
|
, "long": "%d de %B de %Y"
|
91
|
+
, "short_with_placeholders": "%d de %B {{p1}} {{p2}}"
|
91
92
|
}
|
92
93
|
, day_names: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
|
93
94
|
, abbr_day_names: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"]
|
@@ -100,6 +101,7 @@ var DEBUG = false;
|
|
100
101
|
"default": "%A, %d de %B de %Y, %H:%M h"
|
101
102
|
, "short": "%d/%m, %H:%M h"
|
102
103
|
, "long": "%A, %d de %B de %Y, %H:%M h"
|
104
|
+
, "short_with_placeholders": "%d/%m, %H:%M h {{p1}}"
|
103
105
|
}
|
104
106
|
, am: "AM"
|
105
107
|
, pm: "PM"
|
data/spec/spec_helper.rb
CHANGED
@@ -24,6 +24,15 @@ module Helpers
|
|
24
24
|
def temp_path(file_name = "")
|
25
25
|
File.expand_path("../../tmp/i18n-js/#{file_name}", __FILE__)
|
26
26
|
end
|
27
|
+
|
28
|
+
|
29
|
+
def self.included(base)
|
30
|
+
base.let(:backend_class_with_fallbacks) do
|
31
|
+
klass = Class.new(I18n::Backend::Simple)
|
32
|
+
klass.send(:include, I18n::Backend::Fallbacks)
|
33
|
+
klass
|
34
|
+
end
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
RSpec.configure do |config|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.
|
4
|
+
version: 3.0.0.rc8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -132,6 +132,7 @@ files:
|
|
132
132
|
- lib/i18n/js.rb
|
133
133
|
- lib/i18n/js/dependencies.rb
|
134
134
|
- lib/i18n/js/engine.rb
|
135
|
+
- lib/i18n/js/fallback_locales.rb
|
135
136
|
- lib/i18n/js/middleware.rb
|
136
137
|
- lib/i18n/js/utils.rb
|
137
138
|
- lib/i18n/js/version.rb
|
@@ -143,6 +144,11 @@ files:
|
|
143
144
|
- spec/fixtures/default.yml
|
144
145
|
- spec/fixtures/erb.yml
|
145
146
|
- spec/fixtures/js_file_per_locale.yml
|
147
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml
|
148
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml
|
149
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml
|
150
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml
|
151
|
+
- spec/fixtures/js_file_per_locale_without_fallbacks.yml
|
146
152
|
- spec/fixtures/locales.yml
|
147
153
|
- spec/fixtures/multiple_conditions.yml
|
148
154
|
- spec/fixtures/multiple_conditions_per_locale.yml
|
@@ -150,6 +156,7 @@ files:
|
|
150
156
|
- spec/fixtures/no_config.yml
|
151
157
|
- spec/fixtures/no_scope.yml
|
152
158
|
- spec/fixtures/simple_scope.yml
|
159
|
+
- spec/i18n_js_fallback_locales_spec.rb
|
153
160
|
- spec/i18n_js_spec.rb
|
154
161
|
- spec/js/currency.spec.js
|
155
162
|
- spec/js/current_locale.spec.js
|
@@ -191,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
198
|
version: 1.3.1
|
192
199
|
requirements: []
|
193
200
|
rubyforge_project:
|
194
|
-
rubygems_version: 2.
|
201
|
+
rubygems_version: 2.4.3
|
195
202
|
signing_key:
|
196
203
|
specification_version: 4
|
197
204
|
summary: It's a small library to provide the Rails I18n translations on the Javascript.
|
@@ -200,6 +207,11 @@ test_files:
|
|
200
207
|
- spec/fixtures/default.yml
|
201
208
|
- spec/fixtures/erb.yml
|
202
209
|
- spec/fixtures/js_file_per_locale.yml
|
210
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml
|
211
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml
|
212
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml
|
213
|
+
- spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml
|
214
|
+
- spec/fixtures/js_file_per_locale_without_fallbacks.yml
|
203
215
|
- spec/fixtures/locales.yml
|
204
216
|
- spec/fixtures/multiple_conditions.yml
|
205
217
|
- spec/fixtures/multiple_conditions_per_locale.yml
|
@@ -207,6 +219,7 @@ test_files:
|
|
207
219
|
- spec/fixtures/no_config.yml
|
208
220
|
- spec/fixtures/no_scope.yml
|
209
221
|
- spec/fixtures/simple_scope.yml
|
222
|
+
- spec/i18n_js_fallback_locales_spec.rb
|
210
223
|
- spec/i18n_js_spec.rb
|
211
224
|
- spec/js/currency.spec.js
|
212
225
|
- spec/js/current_locale.spec.js
|