Skip to content

Commit 883c08b

Browse files
toshovskiAleksandar Toshovski
authored andcommitted
Add fallback language for localization
1 parent d3ff7ab commit 883c08b

7 files changed

Lines changed: 174 additions & 3 deletions

File tree

app-localize-behavior.html

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@
151151
type: String
152152
},
153153

154+
/**
155+
* Fallback Language if the current language is not yet translated.
156+
*
157+
* For example having only english translation, but trying to open a french localization will return the fallback language
158+
*
159+
* this.resources = {
160+
* 'en': { 'greeting': 'Hello!' }
161+
* }
162+
*
163+
*
164+
*/
165+
fallbackLanguage:{
166+
type: String
167+
},
168+
154169
/**
155170
* The dictionary of localized messages, for each of the languages that
156171
* are going to be used. See http://formatjs.io/guides/message-syntax/ for
@@ -195,7 +210,7 @@
195210
*/
196211
localize: {
197212
type: Function,
198-
computed: '__computeLocalize(language, resources, formats)'
213+
computed: '__computeLocalize(language, fallbackLanguage, resources, formats)'
199214
},
200215

201216
/**
@@ -245,7 +260,7 @@
245260
/**
246261
* Returns a computed `localize` method, based on the current `language`.
247262
*/
248-
__computeLocalize: function(language, resources, formats) {
263+
__computeLocalize: function(language, fallbackLanguage, resources, formats) {
249264
var proto = this.constructor.prototype;
250265

251266
// Check if localCache exist just in case.
@@ -262,9 +277,14 @@
262277
if (!key || !resources || !language || !resources[language])
263278
return;
264279

280+
265281
// Cache the key/value pairs for the same language, so that we don't
266282
// do extra work if we're just reusing strings across an application.
267283
var translatedValue = resources[language][key];
284+
//use fallback key if provided
285+
if(!translatedValue && fallbackLanguage){
286+
translatedValue = resources[fallbackLanguage][key];
287+
}
268288

269289
if (!translatedValue) {
270290
return this.useKeyIfMissing ? key : '';

demo/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
2020
<link rel="import" href="../../paper-styles/typography.html">
2121
<link rel="import" href="x-translate.html">
22+
<link rel="import" href="x-fallback.html">
2223
<link rel="import" href="x-local-translate.html">
2324

2425
<!-- Intl polyfill -->
@@ -30,5 +31,6 @@
3031
<body unresolved>
3132
<x-translate use-key-if-missing></x-translate>
3233
<x-local-translate></x-local-translate>
34+
<x-fallback></x-fallback>
3335
</body>
3436
</html>

demo/locales.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"cats": "I have {numCats, number} cats. Almost {pctBlack, number, percent} of them are black.",
88
"sale": "Sale begins {start, date, medium}, at {time, time, short}. Everything is {price, number, USD}.",
99
"fruit": "{num, plural, =0 {no apples} =1 {one apple} other {# apples}}",
10-
"bananas": "{name} ate {num, plural, =0 {no bananas} =1 {a banana} other {# bananas}} {gender, select, male {at his house.} female {at her house.} other {at their house.}}"
10+
"bananas": "{name} ate {num, plural, =0 {no bananas} =1 {a banana} other {# bananas}} {gender, select, male {at his house.} female {at her house.} other {at their house.}}",
11+
"missing_translation": "Hello world!"
1112
},
1213
"fr": {
1314
"header_1": "Traduction et localisation",
@@ -18,5 +19,8 @@
1819
"sale": "La vente commence le {start, date, medium} à {time, time, short}. Tout est à {price, number, USD}.",
1920
"fruit": "{num, plural, =0 {pas de pommes} =1 {une pomme} other {# pommes}}",
2021
"bananas": "{name} {num, plural, =0 {ne} =1 {} other {}} mange {num, plural, =0 {pas de bananes} =1 {une banane} other {# bananes}} {gender, select, male {chez lui.} female {chez elle.} other {chez eux.}}"
22+
},
23+
"en_US": {
24+
"missing_translation": "Default fallback language"
2125
}
2226
}

demo/x-fallback.html

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<!--
2+
@license
3+
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7+
Code distributed by Google as part of the polymer project is also
8+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9+
-->
10+
11+
<link rel="import" href="../../polymer/polymer.html">
12+
<link rel="import" href="../../paper-toggle-button/paper-toggle-button.html">
13+
<link rel="import" href="../app-localize-behavior.html">
14+
<link rel="import" href="common-styles.html">
15+
16+
<dom-module id="x-fallback">
17+
<template>
18+
<style include="common-styles"></style>
19+
20+
<div class="lang">
21+
<span title="english">🇬🇧 EN</span>
22+
<paper-toggle-button on-change="_toggle" id="switch"></paper-toggle-button>
23+
<span title="french">FR 🇫🇷</span>
24+
</div>
25+
26+
<h4>This will fallback from FR to en_US and use this language, because there is no missing_translation key in french and fallbackLanguage is set to en_US</h4>
27+
<div class="snippet">
28+
<div class="demo">
29+
30+
<div>{{localize('missing_translation')}}</div>
31+
</div>
32+
<div class="code-container">
33+
<code>localize('missing_translation')
34+
</code>
35+
</div>
36+
</div>
37+
38+
</template>
39+
40+
41+
42+
<script>
43+
Polymer({
44+
is: "x-fallback",
45+
46+
behaviors: [
47+
Polymer.AppLocalizeBehavior
48+
],
49+
50+
properties: {
51+
/* Overriden from AppLocalizeBehavior */
52+
language: {
53+
value: 'en',
54+
type: String
55+
},
56+
fallbackLanguage: {
57+
value: 'en_US',
58+
type: String
59+
}
60+
},
61+
62+
attached: function() {
63+
this.loadResources(this.resolveUrl('locales.json'));
64+
},
65+
66+
_toggle: function() {
67+
this.language = this.$.switch.checked ? 'fr' : 'en';
68+
}
69+
});
70+
</script>
71+
</dom-module>

demo/x-translate.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ <h4>{{localize('header_1')}}</h4>
3434
</div>
3535
<div class="code-container">
3636
<code>localize('greeting')</code>
37+
<code>localize('missing_translation')</code>
3738
<code>localize('intro', 'name', 'Batman')</code>
3839
<code>localize('cats', 'numCats', 10000, 'pctBlack', 0.42)</code>
3940
<!-- Dates need to be a valid JavaScript object. For an example, we

test/basic.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<script src="../../intl/locale-data/jsonp/fr.js"></script>
2727

2828
<link rel="import" href="x-translate.html">
29+
<link rel="import" href="x-translate-fallback.html">
2930
<link rel="import" href="x-translate2.html">
3031
<link rel="import" href="x-translate-only-imperative.html">
3132
<link rel="import" href="x-translate-l10n.html">
@@ -39,6 +40,12 @@
3940
</template>
4041
</test-fixture>
4142

43+
<test-fixture id="fallback">
44+
<template>
45+
<x-translate-fallback></x-translate-fallback>
46+
</template>
47+
</test-fixture>
48+
4249
<test-fixture id="missing">
4350
<template>
4451
<x-translate use-key-if-missing></x-translate>
@@ -87,6 +94,16 @@
8794
}
8895

8996
suite('basic', function() {
97+
test('uses fallback language, if translation is missing', function() {
98+
var app = fixture('fallback');
99+
assert.equal(app.language, 'fr');
100+
assert.equal(app.fallbackLanguage, 'en');
101+
assert.equal(app.$.fallback.innerHTML, 'français hello');
102+
103+
});
104+
105+
106+
90107
test('can translate a basic string', function() {
91108
var app = fixture('basic');
92109

@@ -99,6 +116,9 @@
99116
assert.equal(app.$.output.innerHTML, 'bonjour');
100117
});
101118

119+
120+
121+
102122
test('can handle missing keys', function() {
103123
var app = fixture('missing');
104124

test/x-translate-fallback.html

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!--
2+
@license
3+
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7+
Code distributed by Google as part of the polymer project is also
8+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9+
-->
10+
11+
<link rel="import" href="../../polymer/polymer.html">
12+
<link rel="import" href="../app-localize-behavior.html">
13+
14+
<dom-module id="x-translate-fallback">
15+
<template>
16+
<div id="fallback">{{localize('language')}} {{localize('greeting')}}</div>
17+
</template>
18+
19+
<script>
20+
Polymer({
21+
is: "x-translate-fallback",
22+
23+
behaviors: [
24+
Polymer.AppLocalizeBehavior
25+
],
26+
27+
properties: {
28+
language: {
29+
value: 'fr',
30+
type: String
31+
},
32+
fallbackLanguage: {
33+
value: "en",
34+
type: String
35+
},
36+
resources: {
37+
type: Object,
38+
value: function () {
39+
return {
40+
'en': {
41+
'language': "english",
42+
'greeting': 'hello'
43+
},
44+
'fr': {
45+
'language':"français"
46+
}
47+
};
48+
}
49+
}
50+
}
51+
});
52+
</script>
53+
</dom-module>

0 commit comments

Comments
 (0)