Javascript best practice and multilingualism

What is the best practice for a multilingual site using DOM Manipulating with javascript? I am creating some dynamic parts of a website using javascript. My first thought was to use an array with text strings and language code as an index. Is that a good idea?

+51
javascript internationalization
Oct 23 '08 at 7:21
source share
7 answers

When I created multilingual sites before (not very large, so it may not scale too well), I save a number of “language” files:

  • lang.en.js
  • lang.it.js
  • lang.fr.js

Each of the files declares an object, which is basically a map from a keyword to a language phrase:

// lang.en.js lang = { greeting : "Hello" }; // lang.fr.js lang = { greeting : "Bonjour" }; 

Dynamically load one of these files, and then all you need to do is link to the key from your card:

 document.onload = function() { alert(lang.greeting); }; 

There are, of course, many other ways to do this and many ways to make this style, but it’s better: encapsulate it all in a function so that you can process the missing phrase from your “dictionary” gracefully or even do it all with OOP, and let it control dynamics, including files, may even choose language selectors for you, etc.

 var l = new Language('en'); l.get('greeting'); 
+62
Oct 23 '08 at 7:46
source share

There are a few things you need to keep in mind when developing multilingual support:

1 - Separate the code from the data (i.e. do not insert lines strictly into your functions)

2 - create a formatting binding function to eliminate differences in localization. Allow formatting strings ( "{0}" ) is better than concatenation ( "Welcome to" + value ) for many reasons:

  • in some languages, the number is formatted as 1.234.678.00 instead of 1.234.567.00.
  • pluralization is often not as simple as adding "s" at the end of the singular
  • The grammar rules are different and can affect the order of things, so you must allow the addition of dynamic data after the translation hook: for example, "Welcome to {0}" turns into "{0} he youkoso" in Japanese (this happens in almost every language note).

3 - Make sure you can really format the lines after the translation is intercepted, so you can reuse the keys.

4 - Do not fall under any connection to the output of the translator database by the translator utility . If you have multilingual data, create separate tables / rows in your database. I saw how people often make the wrong mistakes (usually for countries and states / provinces in forms).

5 - Create coding rule rules to create keys. The function of the formatter utility (which will look something like translate ("hello world") will take the key as a parameter, and the keys with minor changes are very convenient for maintenance. For example, you can use three keys in the following example: "enter a name", "enter your name: "," enter your name: ". Choose one format (for example, without a colon, trim) and catch inconsistencies in the code views. programmatically, because it can cause false positives.

6 - Remember that HTML markup may potentially be needed in the translation table (for example, if you need to highlight a word in a sentence or have links to medical footnotes). Test it for this.

7 - There are several ways to import language strings. Ideally, you should have several versions of the language.lang.js file, switch between them with server-side code and link to the file from the bottom of the HTML file. Pulling a file through AJAX is also an alternative, but may cause delays. Merging the .js language into your main code file is not recommended as you lose the benefits of file caching.

8 - Check your target languages. This sounds silly, but I saw a serious mistake once, because the programmer did not bother to check for the presence of "é" in the key.

+42
Oct 23 '08 at 12:45
source share
 function Language(lang) { var __construct = function() { if (eval('typeof ' + lang) == 'undefined') { lang = "en"; } return; }() this.getStr = function(str, defaultStr) { var retStr = eval('eval(lang).' + str); if (typeof retStr != 'undefined') { return retStr; } else { if (typeof defaultStr != 'undefined') { return defaultStr; } else { return eval('en.' + str); } } } } 

After adding this to your page, you can work with it as follows:

 var en = { SelPlace:"Select this place?", Save:"Saved." }; var tr = { SelPlace:"Burayı seçmek istiyor musunuz?" }; var translator = new Language("en"); alert(translator.getStr("SelPlace")); // result: Select this place? alert(translator.getStr("Save")); // result: Saved. alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string var translator = new Language("tr"); alert(translator.getStr("SelPlace")); // result: Burayı seçmek istiyor musunuz? alert(translator.getStr("Save")); // result: Saved. (because it doesn't exist in this language, borrowed from english as default) alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string 

If you call a class with the language you specify, English ( ru ) will be selected.

+8
Jul 18 '14 at 19:19
source share

Just found a good article on i18n in javascript:
http://24ways.org/2007/javascript-internationalisation

Although a simple google search with i18n + javascript shows a lot of alternatives.

In the end, it depends on how deep you want. For several languages, one file is enough.

You can use a framework like Jquery , use a range to identify text (with a class), and then use the identifier of each span to find the corresponding text in the selected language.
1 row jQuery done.

+4
Oct 23 '08 at 8:15
source share

After reading the great answers from nickf and Leo, I created the following CommonJS-style language.js language to manage all of my lines (and, optionally, Mustache to format them):

 var Mustache = require('mustache'); var LANGUAGE = { general: { welcome: "Welcome {{name}}!" } }; function _get_string(key) { var parts = key.split('.'); var result = LANGUAGE, i; for (i = 0; i < parts.length; ++i) { result = result[parts[i]]; } return result; } module.exports = function(key, params) { var str = _get_string(key); if (!params || _.isEmpty(params)) { return str; } return Mustache.render(str, params); }; 

And this is how I get the line:

 var L = require('language'); var the_string = L('general.welcome', {name='Joe'}); 
+4
May 12 '15 at 12:53
source share

You should look at what was done in the classic JS components - take things like Dojo, Ext, FCKEditor, TinyMCE, etc. You will find many good ideas.

Usually this ends with the installation of tags, and then you replace the contents of the tag with the translation found in your translation file based on the attribute value.

One thing to keep in mind is the evolution of a set of languages ​​(when your code evolves, you will need to relay it all or not). We save translations in PO files (Gnu Gettext), and we have a script that converts the PO file into a ready-to-use JS file.

Besides:

  • Always use UTF-8 - it sounds silly, but if you are not in utf-8 from the beginning (HTML header + JS encoding), you will quickly disperse.
  • Use the English string as the key to your translations - this way you won’t get things like: lang.Greeting = 'Hello world' - but lang ['Hello world'] = 'Hello world';
+1
Oct 24 '08 at 11:31
source share

For Spring and JavaScript packages, there is a simple solution: generate an i18n array in a template (e.g. JSP) and use it in JavaScript:

JSP:

 <html> <script type="text/javascript"> var i18n = []; <c:forEach var='key' items='<%=new String[]{"common.deleted","common.saved","common.enabled","common.disabled","...}%>'> i18n['${key}'] = '<spring:message code="${key}"/>'; </c:forEach> </script> </html> 

And in JS:

 alert(i18n["common.deleted"]); 

See also Spring permission: messages in javascript for i18n internationalization

0
May 24 '17 at 22:50
source share



All Articles