Lavorare con Intl

L'internazionalizzazione - qualcosa di cui si sentono costantemente gli sviluppatori a parlare, ma che di rado vedono effettivamente le persone che usano nella pratica - sta ricevendo un calcio d'inizio con la nuova API di internazionalizzazione ECMAScript. Attualmente supportato in Chrome 24, Chrome per Android, Firefox 29, IE 11 e Opera 15 (purtroppo nessun supporto Safari), il nuovo spazio dei nomi Intl offre una serie di funzionalità per aggiungere l'internazionalizzazione ai numeri, alle date e all'ordinamento. In questo articolo dimostrerò le principali funzionalità di Intl e ti metterò sulla strada per adottare il supporto per i miliardi di persone su Internet che vivono al di fuori del tuo paese!

Caratteristiche principali

Lo spazio dei nomi Intl copre tre aree principali di funzionalità:

  • Formattare i numeri
  • Date di formattazione
  • Ordinamento delle stringhe

All'interno di ciascuna di queste sono disponibili varie opzioni per controllare sia le impostazioni locali utilizzate per la formattazione sia le opzioni di formattazione. Ad esempio, il formattatore di numeri include il supporto per la gestione della valuta. Il formattatore della data ha opzioni per quali parti della data da visualizzare.

Diamo un'occhiata ad alcuni esempi.

La nostra applicazione

La nostra prima applicazione è un semplice reporter di dati. Usa AJAX per recuperare una serie di dati contenenti date e numeri. Innanzitutto, l'HTML:

Elenco 1: Test1.html:

          

Statistiche attuali

Data visite

Prendi nota del tavolo vuoto. Ecco dove scariceremo i nostri dati. Ora diamo un'occhiata al JavaScript.

Elenco 2: app1.js:

$ (document) .ready (function () // ottiene la tabella dom $ table = $ ("# stats tbody"); // ora, prendi i nostri dati dall'api, che è falso btw $ .getJSON ("stats .json "). done (funzione (s) // itera su stat e aggiungi alla tabella per (var i = 0; i < s.length; i++)  $table.append(""+s[i].date+""+s[i].views+"");  ).fail(function(e)  console.log("we failed"); console.dir(e); ); ); 

Tutto ciò che fa il codice qui è effettuare una chiamata AJAX a un file e rendere il risultato ai dati. Il file di dati, stats.json, è semplicemente un array di dieci valori hard coded. Ecco una parte del file:

[ "data": "2013/04/01", "viste": 938213,  "data": "2013/04/02", "viste": 238213, 

Come puoi vedere, le date sono formattate come mese / giorno / anno e i numeri sono passati, così come sono. Questo rende accettabilmente:

Ma nota che i numeri sono un po 'difficili da leggere senza formattazione. Iniziamo aggiungendo una formattazione ai numeri.

Aggiungere formattazione numerica

Le seguenti modifiche possono essere viste in app2.js e testato con Test2.html. Innanzitutto, modifico il mio codice per chiamare una nuova funzione, NumberFormat:

$ Table.append ( "" + s [i] .date + "" + numberformat (s [i] .views) + "");

Ed ecco questa funzione:

function numberFormat (n) // salva il formatter una volta se (window.Intl &&! window.numberFormatter) window.numberFormatter = window.Intl.NumberFormat (); if (window.numberFormatter) return window.numberFormatter.format (n);  else return n; 

La funzione inizia verificando se Intl esiste come parte del finestra oggetto. Se lo fa, controlliamo quindi se abbiamo già creato il formattatore. Il Intl oggetto crea un oggetto di formattazione che è possibile riutilizzare e dal momento che stiamo formattando un gruppo di numeri, vogliamo solo crearlo una volta. Che è esattamente quello che facciamo non appena vediamo che ne abbiamo bisogno anche noi. Per ora non ci preoccupiamo di opzioni, solo per mantenerlo semplice. Infine, se non ci fosse supporto per Intl del tutto, restituiamo semplicemente il numero così com'è. Il risultato è un miglioramento significativo, con un lavoro minimo:

Freddo! Quindi, come testiamo altre lingue? Potresti essere tentato di verificare le impostazioni del tuo browser. Tutti i browser hanno una preferenza per la lingua, ma sfortunatamente, cambiano la lingua nel browser non è abbastanza. Cambiandolo fa influire sul comportamento del browser. 

Se apri gli strumenti di sviluppo e guardi le richieste di rete, puoi vedere un'intestazione chiamata "Accept-Lanage"cambierà in base alle tue impostazioni. Se aggiungi francese, ad esempio (presumo che tu non sia un madrelingua francese), vedrai"fr"aggiunto a questa intestazione, ma questo non ha impatto Intl. Invece, devi cambiare la lingua del tuo sistema operativo e riavviare il browser. Questo è non spaventoso come sembra. Quando ho provato, ero preoccupato che il mio intero sistema operativo sarebbe cambiato immediatamente. Ma nei miei test, sono stato in grado di cambiare la lingua, riavviare il browser e vedere il cambiamento. Ho subito cambiato di nuovo. Le funzioni di formattazione Intl consentono di ignorare le impostazioni locali correnti e di farne passare una.

Ho modificato l'applicazione per consentire all'utente finale di specificare una lingua tramite un menu a discesa. Ecco la modifica apportata all'HTML. (Questa modifica può essere trovata in test3.html)

Le lingue che ho scelto erano piuttosto arbitrarie. Successivo - Ho aggiornato il mio codice applicazione per ascoltare le modifiche a questo menu a discesa e per controllare le impostazioni internazionali desiderate durante la formattazione.

Elenco 3: app3.js:

function numberFormat (n) if (window.Intl) var lang = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; var formatter = new window.Intl.NumberFormat (lang); return formatter.format (n);  else return n;  function getStats () $ .getJSON ("stats.json"). done (funzione (s) // itera su statistiche e aggiungi alla tabella per (var i = 0; i < s.length; i++)  $table.append(""+s[i].date+""+numberFormat(s[i].views)+"");  ).fail(function(e)  console.log("we failed"); console.dir(e); );  $(document).ready(function()  //get the table dom $table = $("#stats tbody"); //notice changes to drop down $("#langDropdown").on("change", function(e)  $table.empty(); getStats(); ); getStats(); ); 

Partendo in basso, si noti che ho aggiunto un semplice gestore di eventi per le modifiche al menu a discesa. Quando viene rilevata una modifica, la tabella viene svuotata e la funzione GetStats è gestito Questa nuova funzione assorbe semplicemente il codice AJAX utilizzato in precedenza. Il vero cambiamento ora è dentro NumberFormat. Controllo la lingua selezionata e se uno di essi è stato scelto, lo passiamo come impostazioni internazionali a NumberFormat costruttore. Nota che se qualcosa non è stato scelto, per impostazione predefinita navigator.language. Questo ora ci dà un modo per testare rapidamente diverse impostazioni locali e vedere come riproducono i numeri.

Aggiunta della formattazione della data

Ora è il momento perfetto per occuparsi dell'altra colonna di dati: i numeri. Ho seguito lo stesso stile di prima e ho aggiunto una chiamata a una nuova funzione, formato data.

$ Table.append ( "" + DATEFORMAT (s [i] .date) + "" + numberformat (s [i] .views) + "");

Ed ecco formato data (Puoi trovare il codice in app4.js, che è usato da test4.html):

function dateFormat (n) // Utilizzato per la visualizzazione della data var opts = ; opts.day = "numerico"; opts.weekday = "long"; opts.year = "numerico"; opts.month = "long"; if (window.Intl) var lang = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; var formatter = new window.Intl.DateTimeFormat (lang, opts); n = new Date (n); return formatter.format (n);  else return n;  

Questo è molto simile alla formattazione dei numeri, ma questa volta passiamo esplicitamente alcune opzioni quando creiamo il formattatore. Le opzioni specificano sia quali campi sono visibili nella data, sia come appaiono. Ogni parte di una data può essere mostrata o meno, e ognuna ha opzioni diverse. Le opzioni includono:

  • giorno feriale
  • era
  • anno
  • mese
  • giorno
  • ora
  • minuto
  • secondo
  • TimeZoneName

Per un elenco completo dei valori che è possibile utilizzare, consultare la documentazione di MDN per DateTimeFormat, ma ad esempio, i mesi possono essere visualizzati come un numero o in diverse forme testuali. Quindi cosa crea? Ecco la versione inglese:

E qui è in francese:

Forse ti starai chiedendo: cosa copre la posizione di ogni campo? Per quanto ne so, non hai il controllo su questo. Potresti, ovviamente, creare più formattatori e combinarli insieme, ma usando un formattatore il layout dei campi è guidato dalla logica interna. Se spegni il giorno del mese, ad esempio, ecco quello che ottieni: aprile 2013 lunedì. Perché? Onestamente non ne ho idea.

Infine, si noti che è necessario passare un valore di data, non una stringa, al formattatore. Puoi vedere dove uso il costruttore della data nel formattatore per analizzare la mia data basata su stringhe. Questo è - un po 'lento - quindi tienilo a mente quando usi questa funzionalità.

Mostrarmi il denaro

La formattazione della valuta non è un oggetto separato, ma piuttosto un uso facoltativo del formattatore di numeri. Per la prossima demo, abbiamo creato un nuovo file di dati, stats2.json, e ha aggiunto una colonna "vendite" ai nostri dati. Ecco un esempio:

 "Data": "2013/04/01", "viste": 938213, "vendita": 3890.21,  "Data": "2013/04/02", "viste": 238213, "vendite": 9.890,10 

La colonna è stata aggiunta all'HTML (test5.html), aggiunto all'interno del codice JavaScript che scorre sulle righe di dati (vedi app5.js) e passati a una nuova funzione chiamata currencyFormat. Diamo un'occhiata a questo.

function currencyFormat (n) var opts = ; opts.style = "valuta"; opts.currency = "USD"; if (window.Intl) var lang = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; var formatter = new window.Intl.NumberFormat (lang, opts); return formatter.format (n);  else return n;  

La visualizzazione di numeri come valute richiede due valori opzionali. Innanzitutto, uno stile di "valuta" e quindi il tipo di valuta. Esistono anche altre opzioni (come la visualizzazione del nome della valuta). Arriva la parte che potrebbe farti inciampare un po '. tu dovere specificare il tipo di valuta. 

Potresti pensare - come diamine capisco il tipo di valuta per tutti i possibili valori? I valori possibili sono basati su una specifica (http://www.currency-iso.org/en/home/tables/table-a1.html) e in teoria potresti analizzare il loro XML, ma non vuoi farlo. Il motivo per cui è abbastanza ovvio, ma posso dire onestamente che ho dimenticato inizialmente anche. Non si desidera semplicemente visualizzare nuovamente un numero particolare in una valuta specifica della locale. Perché? Perché dieci dollari americani è certamente non lo stesso di dieci dollari in pesos. Questo è abbastanza ovvio e spero di essere l'unica persona a dimenticarlo.

Utilizzando il codice sopra, possiamo vedere i seguenti risultati nelle impostazioni locali francesi. Nota come i numeri sono formattati correttamente per le impostazioni internazionali e il simbolo della valuta viene inserito dopo il numero.

Ordinamento con Collator

Per il nostro ultimo esempio, vedremo il Collator costruttore. I raccoglitori ti consentono di gestire l'ordinamento del testo. Mentre alcune lingue seguono un semplice sistema di ordinazioni dalla A alla Z, altre lingue hanno regole diverse. E, naturalmente, le cose diventano ancora più interessanti quando inizi ad aggiungere accenti. Puoi dire, di sicuro, se viene dopo un? So che non posso. Il costruttore del collator accetta un numero di argomenti per aiutarlo a specificare esattamente come dovrebbe essere ordinato, ma il default probabilmente funzionerà bene per te.

Per questo esempio, abbiamo creato una demo completamente nuova, ma una simile agli esempi precedenti. Nel test6.html, puoi vedere una nuova tabella, per Studenti. Il nostro nuovo codice caricherà un pacchetto JSON di studenti e quindi li ordinerà sul client. I dati JSON sono semplicemente una serie di nomi, quindi salterò la visualizzazione di un estratto. Diamo un'occhiata alla logica dell'applicazione.

Listato 4: app6.js:

funzione sorter (x, y) if (window.Intl) var lang = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; return window.Intl.Collator (lang) .compare (x, y);  else return x.localeCompare (y);  function getStudents () $ .getJSON ("students.json"). done (function (s) // itera su stats e aggiunge alla tabella s.sort (sorter); per (var i = 0; i < s.length; i++)  $table.append(""+s[i]+"");  ).fail(function(e)  console.log("we failed"); console.dir(e); );  $(document).ready(function()  //get the table dom $table = $("#students tbody"); //notice changes to drop down $("#langDropdown").on("change", function(e)  $table.empty(); getStudents(); ); getStudents(); ); 

Come ho detto, questo codice è molto simile agli esempi precedenti, quindi concentrati su getStudents primo. La linea cruciale qui è: s.sort (sorter). Stiamo utilizzando la funzione incorporata per gli array per eseguire l'ordinamento tramite una funzione personalizzata. Quella funzione sarà passata due cose da confrontare e deve ritornare -1, 0, o 1 per rappresentare come devono essere ordinati i due elementi. Adesso guardiamo il sorter.

Se abbiamo un Intl oggetto, creiamo un nuovo Collator (e di nuovo, ti stiamo permettendo di passare in un locale) e poi eseguiamo il confrontare funzione. Questo è tutto. Come ho detto, ci sono opzioni per modificare il modo in cui le cose sono ordinate, ma possiamo usare i valori predefiniti. Il fallback è localeCompare, che tenterà anche di utilizzare la formattazione specifica della locale, ma ha (in questa forma) un supporto leggermente migliore. Potremmo verificare anche questo supporto e aggiungere un altro fallback per veramente buon supporto, ma lascerò questo per te, come esercizio.

Abbiamo anche modificato il front end per usare lo svedese come lingua. L'ho fatto perché l'eccellente documentazione di MDN ha dimostrato che era un buon modo per vedere l'ordinamento in azione. Ecco il tipo inglese dei nomi dei nostri studenti:

E qui è in svedese:

Nota come ätest è ordinato in modo diverso. (Scusa, non riuscivo a pensare a un nome che inizia con ä.)

Incartare

Tutto sommato, il Intl la classe fornisce alcuni molto modi semplici per aggiungere una formattazione specifica per il tuo codice. Questo è certamente qualcosa che puoi trovare ora, probabilmente in poche migliaia di librerie JavaScript diverse, ma è bello vedere i produttori di browser aggiungere supporto direttamente nella lingua stessa. La mancanza di supporto iOS è un peccato, ma speriamo che verrà presto aggiunto.

Grazie a Mozilla Developer Network per la sua eccellente documentazione Intl.