Closed jshcrowthe closed 8 years ago
Hey! Great to see someone else is thinking about this!
I have the following question regarding this proposal: How will translations be loaded? I would like to allow the page author to specify where they come from and allow the component author to just make use of the translate function. I think a <link>
-style custom element for specifying where translations come from would still be a nice thing, as it's declarative.
Oh, and using <html lang="">
as input would make sense, too, IMO.
@marcelklehr the translations are being loaded in two different ways (depending on the environment):
The files are loaded via AJAX
(in my implementation I use fetch
instead of XMLHttpRequest
). Based on which language is currently set for the application (ATM v2 ofwc-i18n
only allows 1).
You would either inline your resources (similar to how it is done in https://github.com/PolymerElements/app-localize-behavior) at dev time or you can use a tool like https://github.com/jshcrowthe/gulp-wc-i18n to inline them for you at build time. Either way, you don't want to have a network request, per component, to render text to the screen (that can get costly real fast).
Again, app-localize-behavior handles this by letting you pass a resources
prop or by specifying the location of 1 large locale file. This file gets cached so using AJAX
to load it (which IMO isn't optimal due to the network request), totally works because the request is really only made once.
So, to your point. We could definitely allow the extension of the loading behavior and look for an optional function loadLocales
function (or something of the like). However this solution is focused around component translations as opposed to page level.
If we wanted to add a function as a property of the WCI18n
object, we could totally allow for this. I just haven't built that functionality currently (though it wouldn't be difficult at all). If that was something you wanted to PR after I merge this v2
branch, then I'd be all for supporting it.
NOTE: The API for this component has changed since the original PR. See the updated README.md for the updated API
I made assumptions about the architecture of Polymer apps that turned out to be wrong. I think the current version is very good. To improve it further, http://formatjs.io/ could be used (especially the ICU message format is really worth adopting). Also, from reading the README I'm not sure where the app-global language is set (for this <html lang="">
could be used, but I don't know if this is still the state of-the-art way to do that ;) ).
Originally I wanted to use the IntlMessageFormat
but the polyfill for the Intl
object with its locales is huge.
That said http://caniuse.com/#feat=internationalization shows that IE 11 even supports this (Safari 9.1 was the only straggler), so maybe the Polyfill need is moot.
It'd even let us extend the API a little and make it more flexible.
For the default language, I would lean towards navigator.language
or en
as defaults.
The only problem is building the language fallback when you get two codes that need to fallback to a common root:
e.g.
en-US
en-UK
These both fallback to en
The declarative method would be to define the language on any component as they will all end up using the same value.
Version 2.0 Release
I have decided to approach the problem a little differently. In doing so I have made some breaking changes but have simplified the API drastically.
Breaking Changes
Lets get these out of the way up front. Lots of changes:
wc-i18n
orwc-i18n-src
WCI18nBehavior
->WCI18n
_localeMapper
(This will be added inv2.1
)WCI18n.setLocale
The new API
Before the API required way to much boilerplate to actually get functioning well. This refactor has eliminated a lot of that and simplified it to three things. Consider the component below:
There are 3 keys to using this component:
<link rel="import" href="../wc-i18n/wc-i18n.html">
WCI18n('v2-comp')
[[_i18n.KEY_NAME]]
The first two points are the only boilerplate required to bootstrap your component's translations. The first is pretty self explanatory, HTML import
wc-i18n.html
into your application. The second is the inclusion of theWCI18n
behavior. This is a function that must be called with the name of your component (the same value that is set as theis
attribute). It will then, for local dev, look in thelocales
directory for the locales as before.After those two steps, you simply use the
_i18n
object provided to you as a part of the behavior. You are also given 3 methods that you can use:setLocales(lang, locales)
: This method will allow you to override the locales for a given component. NOTE: This will modify all instances of this component throughout the app.getLocales(lang)
: This method fetches the locales for a given language and returns them as an object.translate(string, lang)
: This method translates a given string to the passed language.NOTE: In all instances, the language, if not passed, defaults to
WCI18n.getLocale()
Most people will use the
_i18n
object and data bind to it inside of their applications.Prod Use
gulp-wc-i18n
supports bothv1
andv2
ofwc-i18n
. You can, in your build pipeline, use that tool to inline locales for you.