Last night, I got application-wide localization working in my Polymer application. It is not real internationalization and localization—it only allows for a single application-wide localization, but it is a start. Tonight, I hope to use some of Dart's
intl package to come up with something better. Specifically, I would like to be able to dynamically change the locale at runtime.There is an example of Polymer internationalization in the Dart repository. I am not quite following along with that, but it does prove invaluable.
Yesterday's solution relied on attributes and
<content> tags to include information from other locales: <hello-you hello="Bonjour" done="Fin">
<p>Présentez-vous une expérience personnalisée incroyable!</p>
</hello-you>Those attributes and <content> are then included in the template as:<polymer-element name="hello-you">
<template>
<div>
<h2>{{hello}} {{your_name}}</h2>
<p>
<input value="{{your_name}}">
<input type=submit value="{{done}}!" on-click="{{feelingLucky}}">
</p>
<p class=instructions>
<content></content>
</p>
</div>
</template>
<script type="application/dart" src="hello_you.dart"></script>
</polymer-element>As I mentioned, the attributes like hello and done have to to hard-coded in the page for this approach to work. Instead, I want those properties to be dynamic getters.In the end, I do not even use the
intl package, which seems useful for strings requiring parameters (numbers or dates). I find that I can achieve what I want with a Labels class like:class Labels {
var locale;
Labels(this.locale);
operator [](label) {
var lookup;
switch (locale) {
case 'fr' : lookup = fr; break;
default: lookup = en;
}
return lookup[label];
}
static Map get en => {
'hello': 'Hello',
'done': 'Done',
'instructions': 'Introduce yourself for an amazing personalized experience!'
};
static Map get fr => {
'hello': 'Bonjour',
'done': 'Fin',
'instructions': 'Présentez-vous une expérience personnalisée incroyable!'
};
}The localized labels are included as static methods. An instance of the Labels class provides an [] lookup, switching the labels based on the current locale.The various getters in the Polymer can then be written as lookups of
Labels:@CustomTag('hello-you')
class HelloYou extends PolymerElement {
// ...
@published String locale = 'en';
HelloYou.created(): super.created();
String get hello => _labels['hello'];
String get done => _labels['done'];
String get instructions => _labels['instructions'];
var __labels;
get _labels {
if (__labels == null) __labels = new Labels(locale);
return __labels;
}
// ...
}That still will not quite work if I wanted to allow a human to change the locale on the fly, but it allows the Polymer to change locales with a simple attribute:<hello-you locale="fr"></hello-you>Which results in:

I will pick back up tomorrow trying to allow a human to hot swap locales. I would also like to come up with a contrived example to use for
intl messages. I do not think that I will end up using them in Patterns in Polymer (there's not an easy JavaScript equivalent), but I misunderstood them badly enough tonight to confuse myself into thinking that I needed them. This seems a fine chance to understand what they really can do.Day #973
I played with this a while ago and like the approach using filters http://stackoverflow.com/questions/20323815/how-to-initialize-internationalization-for-a-polymer-element-before-it-loads-on/20377702#20377702
ReplyDeleteThat is pretty nice. The filters make the Polymer template self-documenting for which fields get i18n. I'll give that a try in a day or two. Thanks!
Delete