Reputation: 5000
I'm devising an i18n helper for JavaScript and would like some input on the implementation.
In the basic scenario it should provide some sort of lookup functionality based on a locale object: (with support for variables)
var locales = {
en : {
pages : {
myPage1 : {
title : "A title with <em>highlighted %s</em>",
}
}
}
}
function _(path) {
//lookup and return translation
}
_(pages.myPage1.title, "text") => "A title with <em>highlighted text</em>"
Later, I'd like to implement support for plural/singular etc:
var locales = {
en : {
pages : {
myPage1 : {
title : "A title with <em>%s text</em>",
tickets : {
_0 : "0 tickets left",
_1 : "1 ticket left",
_1+ : "%s tickets left"
}
}
}
}
}
function _n(path, count) {
//lookup and return translation
}
_n(pages.myPage1.ticketsLeft,5) => "5 tickets left"
... And also integrate this with a templating engine:
<h1>{{ _(pages.myPage1.title) }}</h1>
<p>{{ _n(pages.myPage1.ticketsLeft, {{ variable }} ) }}</p>
Questions:
What pitfalls are there in basic i18n and what does the implementation above lack that should be considered from the beginning?
How would you code the actual methods _(), _n() so that they work with an object as the one given?
Any ideas on the template integration - how should it be done?
Are there any "translation crowd-sourcing services" that work well together with JavaScript?
Upvotes: 0
Views: 688
Reputation: 201818
In addition to the plural form issue that Paweł Dyda described, there are a few other potential problems:
The localize() method in Globalize.js is very simple, suitable for the case of a set of string literals to be localized (translated). But you can write your own, more advanced code so that you add properties to the culture objects there.
Overall, much depends on the intended scope: how many languages (and what types of languages) are you going to cover, and what kinds of localization different from simple string localization will you need? Implementing a general scheme for handling expressions of the type “n items” is not simple—CLDR gives you sets of rules, but you would need to code them, and in translations, you would need to request for all the relevant inclined forms of a noun like “item.” If such expressions occur in some specific context(s) only, it might be feasible to reformulate things so that you don’t say “n tickets left” but “Number of tickets left: n.” This would be much easier to implement: just string localization and number localization.
Upvotes: 1
Reputation: 18662
Ad 1. Your assumption on just one plural form is wrong. Some languages have few different plural forms (Polish translation of your example):
one: Pozostał jeden bilet.
few: Pozostały 2 bilety.
many: Pozostało 5 biletów.
other: Pozostało 1,5 biletu. // OK, this one doesn't make sense but that's how it would be translated if it does...
Please find more information in CLDR. Notice plural forms for Arabic.
Ad 2. For translating, I would use Globalize since it has this functionality more or less built-in (there is a Localize()
function). The only problem from my observation would be Locale fall-back. You actually need to ensure that something like de-AT (German/Austria) fall back to de (German/country invariant) unless you have specific translations for given language. The Chinese might be bigger problem, you should not under any circumstances fall back to Chinese Simplified (if zh points to it), if you have Chinese Traditional Locale. Using zh-Hans and zh-Hant might be a good idea.
As for plural forms, you probably need to incorporate the data from CLDR chart above and use some logic based on Locale. I would probably extend Globalize's culture files by adding plural forms and then by calling FindClosestCulture()
(if I recall it correctly) I would check what sort of rule should I use for this context (Locale and number). Then reading appropriate message with Localize()
. Of course one would need to write messages with appropriate keys, like:
tickets-one : One ticket left.
tickets-other: : {0} tickets left.
BTW. I would use numbered placeholders. The reason is, sometimes you need to place more than one. In that case if you have two exactly the same %s
placeholders, translators won't be able to re-order the sentence. And that is required more often than you think (many languages have totally different grammar rules than English).
Ad 3. Depending on your templating engine...
Ad 4. That depends on how you want to integrate this. Usually, server-side translation is used, so you actually write out JavaScript file from your application back-end. In that case depending on technology you are using in your back-end, you might use simple properties files or more complicated (but often better) solutions like Gettext. For both formats you can easily find crowdsourcing platform (i.e. Launchpad supports the latter out of the box). If you want someone to translate your JavaScript files like the one you are showing above, that's actually not very good idea. One problem with it, it is non-standard so many people won't actually know how to translate it. Another, it is very easy to actually damage it by forgetting to add a comma, the colon or curly brace. These are the errors you (or some unfortunate soul using what you have written) would have to deal with.
Upvotes: 1