i18n-js 3.0.0.rc7 → 3.0.0.rc8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|