i18n plugin #26

Closed
unscriptable opened this Issue Oct 13, 2011 · 13 comments

Comments

Projects
None yet
6 participants
Owner

unscriptable commented Oct 13, 2011

Create the i18n plugin. It should initially behave like dojo's and RequireJS's i18n plugin. (Later, we'll likely add a feature to prefetch / inject strings that may be stored and/or retrieved by an alternative mechanism. For instance, a project could use this feature to preload a customized bundle for a particular client or OEM.)

Owner

unscriptable commented Oct 13, 2011

copying @asilvas

unscriptable was assigned Nov 30, 2011

The current requireJS function returns a collection of strings, but I think it would be cool if it was a REF with strings as a property. Maybe a REF to some singleton class, so that var i18n = REF.getInstance(). Then we could do things like i18n.setLocale(code) and i18n.getString(key) and attach events like i18n.bind("localeChanged",onLocaleChanged)

Some of the solutions I have seen, offer a substitution/template scheme built into i18n.

imho templating should be left out because its easy enough to fetch the value, then compile in a template function from underscore/mustache/etc/etc/etc

_.template(i18n.getString("foo"),{bar:bar});

As templating solutions get stronger and more feature rich (conditionals and so forth) any built in support for it here would just get in the way.

Owner

unscriptable commented Feb 28, 2012

I've often dreamed of being able to switch the locale without a reload. Seems like we've just about got all of the components in @cujojs to do that now. I'll put a bit more thought into that. Sounds like a very cool idea! :)

-- John

gamtiq commented Mar 1, 2012

Hello,

FYI.
I use RequireJS's i18n plugin with curl in my application and they work fine together. The only little problem/drawback I’ve encountered is that the plugin doesn’t allow to use properly a deep (more than 2 levels, i.e. menu.text.item1 instead of menu_text.item1) hierarchy of messages that isn’t fully translated for all alternative locales. In other words, if you have menu.text.item1 and menu.text.item2 in root bundle and only menu.text.item1 in a specific translation bundle then you won’t have menu.text.item2 from root bundle as default text (menu.text.item2 will be undefined). It is because plugin’s mixin function isn’t recursive.

Denis

Owner

unscriptable commented Mar 1, 2012

That's great to hear, @gamtiq! I am glad it works! -- John

Hi John,

I've built a Facebook-style Bootloader on top of curl.js for my employer (a 40M PVs/month e-commerce site), and I've written a custom i18n plugin for our site, using an approach similar to RequireJS. Surprisingly, it took just 35 lines of Javascript to make the fully functional plugin, including built-in error handling (hooray for the AMD plugin format).

It seems to me that most of the tricks (writing locale to session and/or HTML, choosing locale fallbacks, routing of async requests to the resource handler) happen on the server side, whereas the client side plugin can be kept relatively lightweight. In other words, why not keep it simple and let the app developers take it from there?

And while I agree that no-refresh locale switching is a noble dream, I don't think it's realistic on most existing sites. You'd need to bind locale update events to not only content nodes (which are usually served by a non-JS server), but also every meta tag (title, description, opengraph tags, etc.), image tag (that may contain localized text), external CSS file (since they often reference one or more localized image sprites), as well as potentially client side templates (which shouldn't include text, but we know from experience they sometimes do). Worse yet, for some sites you may run into encoding or text direction issues, if one locale uses Western European ISO-8859-1, while another uses Chinese Big5 or Arabic Windows-1256.

Owner

unscriptable commented Apr 18, 2012

Thanks for the input @JensRoland! Encoding is something I don't have an answer for, yet. :)

FWIW, I believe refresh-less locale switching is entirely doable on any site that runs as a single-page app (with #! style routing) or on any site running full-stack Javascript. Then again, on sites like those, you can probably achieve this without any specific help from the i18n plugin.

Owner

unscriptable commented Nov 16, 2012

There's a version of this in the dev branch. Needs docs, of course.

The initial issue description seems to imply that this should operate like RequireJS and Dojo's i18n plugins, but it doesn't seem to (at least, as of curl 0.7.3) - it doesn't appear to expect the root object in the root bundle, and expects translations in bundlename/language.js instead of language/bundlename.js. (Contrast the expectations of curl's i18n plugin with http://requirejs.org/docs/api.html#i18n)

So I guess my question is, do you believe this inconsistency is a bug, or by design?

Owner

unscriptable commented Apr 29, 2013

Hey @kfranqueiro!

This is by design. I hadn't realized that the dojo and requirejs i18n plugins had increased in complexity when I wrote this issue. The dojo and requirejs i18n plugins seem to be trying to be ultra-general-purpose. Imho, the tools should make simple things simple. It's easy to create and/or adapt the plugins, so more advanced users -- or those who wish to do things differently -- should be able to create their own i18n plugin.

Sorry if the lack of documentation caused you some hassles. See #190.

-- John

purge commented Oct 25, 2013

The requireJS i18n plugin specifies available languages in the base language file. This avoids the need to traverse language parents at runtime to find which languages are available so you don't get numerous 404s. I'd say this is probably the right way to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment