in featured, sviluppo

Localizzazione dei file javascript

Per la validazione di alcuni form ho avuto la necessità di localizzare le stringhe di errore gestite all’interno di un file Javascript.
Volevo un sistema che non fosse eccessivamente invasivo, simile al gettext che uso con php ma che fosse indipendante da codice serverside e che mi permettesse di caricare e cambiare il file con le riserse localizzate anche a runtime.

Quello che ne è uscito mi piace molto e penso che sia anche sufficentemente scalabile pur avendo come limite il fatto di lavorare su array di stringhe un oggetto json piuttosto che su file compilati.

In pratica dopo aver dichiarato l’oggetto in cui “cercare” le traduzioni, ho preparato una funzione che verifica la presenza della stringa localizzata e nel caso non venga trovata mi restituisse quella “non localizzata”.

var Localization = {};
function _e( s ){
if(Localization && (v=Localization[s]) ) return v;
return s;
}

Usando questa funzione all’interno dei miei file js sono in grado di separare (ed eventualmente rimandare) le problematiche relatavie alla localizzazione rimanendo concentrato sul codice.
Nell’esempio qui sotto viene visualizzato un alert con un bel “ciao” sino a quando non viene caricata una risorsa in lingua

alert( _e(“ciao”) );

Per caricare il file con le risorse localizzate includo lo script a runtime con “getScript” (magari dopo aver letto un cookies…)

function LoadLocale( locale ){
/* es. LoadLoacale(“en_EN”); */
var Localization_path = “languages/”;
Localization = {};
try {
jQuery.getScript( Localization_path + locale + “.js”);
} catch(e) {}
}

Questa la struttura del file di risorse (en_EN.js) che nel momento in cui viene richiamata ridefinisce completamente l’oggetto “Localization”

// en_EN – javascript localization file
var Localization = {
“errore” : “error”,
“ciao” : “hello”,
“nome” : “name”,
“sito web” : “website”
}

Uno dei vantaggi di questo sistema è che andrò a localizzare solo ciò che mi serve con un approccio non intrusivo.
In atre parole se la stringa o il file non vengono trovati viene restituita la stringa non localizzata.
Ancora una nota per chi volesse usarlo: dentro LoadLocale c’è una chiamata a jQuery che quindi va considerato tra i requisiti necessari.

Per migliore le performance, indipendentamente dalla dimensione del file della localizzazione, sarebbe consigliabile minimizzare i file javascript con strumenti tipo questo.

Questi alcuni link da cui ho preso ispirazione.

Write a Comment

Comment

  1. non è un po limitante il fatto di avere un json “piatto” per la gestione delle label?
    sarebbe nettamente più comodo permettere una struttura gerarchica del tipo:

    var Localization = {
    “errors” : {
    “serverError”: “Errore del server”,
    “validationError”: “Errore di validazione”
    },
    “notifications”: {
    “addSuccess”:”Elemento aggiunto con successo”
    },
    “yes”: “Sì”
    }

    per una struttura di questo tipo mi vengono in mente almeno due soluzioni:
    – utilizzare eval all’interno della funzione _e per sfruttare l’indice gerarchico “errors.serverError”
    – utilizzare split(“.”) e ciclare sul vettore cosi ottenuto

  2. Ciao Alberto,
    il tuo approccio è sicuramente interessante ma se ho capito bene verrebbe meno l’apporoccio non ivasivo.

    nella procedura di validazione io adesso scivo direttamente cose come questa:

    _e(“Inserire una mail valida”)
    _e(“Il campo cognome è obbligatorio”)

    e se nel file di localizzazione non trovo le stringe viene visualizzato il testo passato come argomento.

    Con il metodo da te proposto cosa dovrei scrivere?
    _e(“errors.validationError”) ?
    e se il file di localizzazione non è presente o non è completo?

    fammi sapere se ho capito correttamente quella che è la tua idea…

  3. Hmm dal tuo piccolo esempio mi era sembrato di capire che le chiavi dell’oggetto json fossero un po’ più “semplici” e non delle vere frasi.

    Sono d’accordo sulla non invasività del tuo approccio, ma mi pare che sia poco scalabile in applicazioni di una certa entità soprattutto per il rischio di avere il file di localizzazione troppo disordinato.

    Nel mio caso ovviamente in caso di file non presente o non completo l’applicazione lancierà un errore come credo sia giusto in caso di mancanza di una stringa.

    Secondo me si tratta di due approcci diversi proprio per la loro natura.
    Il mio mi sembra più “enterprise” con focus verso la scalabilità, l’ordine e una più forte regolamentazione mentre il tuo mi sembra più “easy” con focus verso la velocità di sviluppo e la non invasività 🙂

  4. l’approccio è quello utilizzato anche nelle localizzazioni gettext con php (vedi qui e qui).

    per la scalabilità io non vedo particolari problemi…
    …o meglio forse può essere lungo andare a mantenere le traduzioni non avendo applicativi come POedit ma se ci facciamo aiutare da un piccolo script bash che ci prepara l’elenco delle stringhe da tradurre il più è fatto…

    sbaglio?

  5. no, no, non sbagli!

    quello che non mi convince appieno è l’utilizzo di più “sistemi” per questa gestione quando è possibile sfruttare solamente JavaScript e una funzione di qualche riga per fare il tutto.

    Però qua non stiamo discutendo più di efficacia o meno di una soluzione ma di aspetti più filosofici 🙂