Best practice javascript e multilingua

qual è la migliore pratica per il sito web in più lingue utilizzando DOM Manipulating con javascript? Costruisco alcune parti dinamiche del sito web usando javascript. Il mio primo pensiero è stato usare un array con le stringhe di testo e il codice della lingua come indice. E ‘questa una buona idea?

Quando ho creato siti multilingue (non molto grandi, quindi non è ansible scalare troppo bene), tengo una serie di file “linguistici”:

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

Ciascuno dei file dichiara un object che è fondamentalmente solo una mappa dalla parola chiave alla frase della lingua:

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

Carica dynamicmente uno di questi file e quindi tutto ciò che devi fare è fare riferimento alla chiave dalla tua mappa:

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

Ci sono, naturalmente, molti altri modi per farlo, e molti modi per fare questo stile ma meglio: incapsulare tutto in una funzione in modo che una frase mancante dal tuo “dizionario” possa essere gestita con garbo, o addirittura fare il tutto usando OOP, e lascia che gestisca la dynamic includendo i file, potrebbe forse anche disegnare selettori di lingua per te, ecc.

 var l = new Language('en'); l.get('greeting'); 

Ci sono alcune cose che devi tenere a mente quando si progetta il supporto multilingua:

1 – Separa il codice dai dati (cioè non stringere le stringhe direttamente nelle tue funzioni)

2 – creare una funzione di hook di formattazione per gestire le differenze di localizzazione. Consentire le stringhe formattabili ( “{0}” ) è meglio che concatenare ( “Benvenuto in” + valore ), per molti motivi:

  • in alcune lingue, un numero è formattato come 1.234.678,00 anziché 1.234.567,00
  • la pluralizzazione spesso non è così semplice come accodare una “s” alla fine del singolare
  • le regole grammaticali sono diverse e possono influire sull’ordine delle cose, quindi è necessario consentire l’aggiunta di dati dinamici dopo il hook di traduzione: ad esempio, “Welcome to {0}” diventa “{0} he youkoso” in giapponese (questo accade in praticamente ogni lingua, intendiamoci).

3 – Assicurarsi di poter effettivamente formattare le stringhe dopo l’esecuzione del hook di traduzione, in modo da poter riutilizzare le chiavi.

4 – Non eseguire, in nessuna circostanza, uscite del database sull’utilità del traduttore . Se disponi di dati multilingue, crea tabelle / righe separate nel tuo database. Ho visto persone che si sbagliano senza troppi problemi spesso (di solito per paesi e stati / province nelle forms).

5 – Creare regole di pratica di codifica esplicite per la creazione di chiavi. La funzione di utilità del formatter (che assomiglierà a translate (“hello world”) prenderà una chiave come parametro, e le chiavi con leggere variazioni renderanno molto fastidiosa la manutenzione.Ad esempio, potresti avere tre chiavi nel seguente esempio: “inserisci il tuo nome”, “inserisci il tuo nome:”, “inserisci il tuo nome:”. Scegli un formato (ad es. senza colon, ritagliato) e rileva discrepanze nelle revisioni del codice. Non eseguire questo filtraggio a livello di codice, poiché può generare false positivi.

6 – Ricordati che il markup HTML potrebbe essere necessario nella tabella di traduzione (ad esempio se hai bisogno di mettere in grassetto una parola in una frase, o se hai riferimenti medici a piè di pagina). Prova per questo ampiamente.

7 – Esistono diversi modi per importare le stringhe della lingua. Idealmente, dovresti avere più versioni di un file language.lang.js, cambiarle tra loro con il codice lato server e fare riferimento al file dalla parte inferiore del file HTML. Anche tirare il file tramite AJAX è un’alternativa, ma potrebbe introdurre ritardi. L’unione di language.js nel file di codice principale non è consigliabile, poiché si perdono i vantaggi del caching dei file.

8 – Test con le lingue di destinazione. Sembra sciocco, ma ho visto un bug serio una volta perché il programmatore non si è preoccupato di verificare l’esistenza di “é” nella chiave.

 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); } } } } 

Dopo aver aggiunto questo alla tua pagina, puoi lavorarci in questo modo:

 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 

Se chiami la class con una lingua che non hai definito, sarà selezionato English ( en ).

Ho appena trovato un bell’articolo su i18n in javascript:
http://24ways.org/2007/javascript-internationalisation

Anche se una semplice ricerca su google con i18n + javascript rivela molte alternative.

Alla fine, dipende da quanto profondo vuoi che sia. Per un paio di lingue, è sufficiente un singolo file.

Potresti usare un framework come Jquery , usare uno span per identificare il testo (con una class) e quindi usare l’id di ogni span per trovare il testo corrispondente nella lingua scelta.
1 linea di Jquery, fatto.

Dopo aver letto le grandi risposte di nickf e Leo, ho creato il seguente stile CommonJS language.js per gestire tutte le mie stringhe (e opzionalmente, i baffi per formattarli):

 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); }; 

E questo è il modo in cui ottengo una stringa:

 var L = require('language'); var the_string = L('general.welcome', {name='Joe'}); 

Dovresti esaminare cosa è stato fatto nei componenti JS classici: prendere cose come Dojo, Ext, FCKEditor, TinyMCE, ecc. Troverai molte buone idee.

Di solito finisce per essere una sorta di attributi che imposti sui tag, e quindi si sostituisce il contenuto del tag con la traduzione trovata nel file di traduzione, in base al valore dell’attributo.

Una cosa da tenere a mente è l’evoluzione del set di lingue (quando il codice si evolve, sarà necessario ritrasformare il tutto o no). Manteniamo le traduzioni in PO Files (Gnu Gettext), e abbiamo uno script che trasforma il file PO in file JS pronti all’uso.

Inoltre:

  • Usa sempre UTF-8 – questo suona stupido, ma se non sei in utf-8 dall’inizio (HTML head + JS encoding), ti prenderai molto presto.
  • Usa la stringa inglese come chiave per le tue traduzioni – in questo modo non ti ritroverai con cose come: lang.Greeting = ‘Hello world’ – ma lang [‘Hello world’] = ‘Hello world’;

Per i pacchetti Spring e JavaScript ci sono soluzioni semplici: generare array i18n in template (es. JSP) e usarli in JavaScript:

JSP:

    

E in JS:

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

Vedi anche Risolvi spring: messaggi in javascript per l’internazionalizzazione i18n