Travailler avec Intl

L'internationalisation - une chose que les développeurs parlent sans cesse, mais que les utilisateurs utilisent rarement - est en train de prendre des risques avec la nouvelle API d'internationalisation ECMAScript. Actuellement pris en charge par Chrome 24, Chrome pour Android, Firefox 29, IE 11 et Opera 15 (malheureusement, pas de support Safari), le nouvel espace de noms Intl fournit un ensemble de fonctionnalités permettant d’internationaliser vos chiffres, vos dates et votre tri. Dans cet article, je vais vous présenter les principales fonctionnalités d'Intl et vous mettre sur la voie de l'adoption d'un soutien pour les milliards de personnes sur Internet qui vivent en dehors de votre pays.!

CARACTERISTIQUES de base

L'espace de noms Intl couvre trois domaines principaux de fonctionnalité:

  • Formater des nombres
  • Dates de formatage
  • Tri des chaînes

Chacune de ces options contient diverses options permettant de contrôler à la fois les paramètres régionaux utilisés pour le formatage et les options de formatage. Par exemple, le formateur de nombres inclut la prise en charge de la gestion des devises. Le formateur de date a des options pour les parties de la date à afficher.

Jetons un coup d'oeil à quelques exemples.

Notre application

Notre première application est un simple reporter de données. Il utilise AJAX pour récupérer un ensemble de données contenant des dates et des nombres. Tout d'abord, le HTML:

Listing 1: test1.html:

          

Statistiques actuelles

Rendez-vous amoureux Les visites

Prenez note de la table vide. C'est là que nous allons vider nos données. Voyons maintenant le JavaScript.

Listing 2: app1.js:

$ (document) .ready (function () // récupère la table dom $ table = $ ("# stats tbody"); // maintenant, récupérons nos données à partir de l'API, ce qui est faux entre $ .getJSON ("stats .json "). done (fonction (s) // itérer sur les statistiques et ajouter à la table pour (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); ); ); 

Tout ce que le code fait ici, c'est faire un appel AJAX vers un fichier et rendre le résultat aux données. Le fichier de données, stats.json, est simplement un tableau de dix valeurs codées en dur. Voici une partie du fichier:

["date": "01/04/2013", "vues": 938213, "date": "04/02/2013", "vues": 238213, 

Comme vous pouvez le constater, les dates sont au format mois / date / année et les chiffres sont passés tels quels. Cela rend de manière acceptable:

Mais notez que les chiffres sont un peu difficiles à lire sans formatage. Commençons par ajouter un peu de formatage aux nombres.

Ajout de la mise en forme numérique

Les modifications suivantes peuvent être vues dans app2.js et testé avec test2.html. Tout d'abord, je vais modifier mon code pour appeler une nouvelle fonction, Format de nombre:

$ table.append ("" + s [i] .date + "" + numberFormat (s [i] .views) + "");

Et voici cette fonction:

function numberFormat (n) // met en cache le formateur une fois si (window.Intl &&! window.numberFormatter) window.numberFormatter = window.Intl.NumberFormat (); if (window.numberFormatter) retourne window.numberFormatter.format (n);  else return n; 

La fonction commence par vérifier si Intl existe dans le cadre du la fenêtre objet. Si tel est le cas, nous vérifions ensuite si nous avons déjà utilisé le formateur. le Intl object crée un objet de mise en forme que vous pouvez réutiliser, et comme nous mettons en forme un ensemble de nombres, nous ne voulons le créer qu’une fois. Ce qui est exactement ce que nous faisons dès que nous constatons que nous en avons aussi besoin. Nous ne nous préoccupons pas des options pour l'instant, juste pour que ce soit simple. Enfin, s’il n’existe aucun soutien pour Intl du tout, nous renvoyons simplement le numéro tel quel. Le résultat est une amélioration significative, avec un travail minimal:

Cool! Alors, comment testons-nous d'autres langues? Vous pourriez être tenté de vérifier les paramètres de votre navigateur. Tous les navigateurs ont une préférence pour la langue, mais malheureusement, changer de langue dans le navigateur n'est pas assez. Le changer Est-ce que impact sur le comportement du navigateur. 

Si vous ouvrez vos outils de développement et examinez les requêtes réseau, vous pouvez voir qu'un en-tête appelé "Accepter-Lanage"changera en fonction de vos paramètres. Si vous ajoutez le français, par exemple (je suppose que vous n'êtes pas francophone), vous verrez"fr"ajouté à cet en-tête. Mais cela n'a pas d'impact Intl. Au lieu de cela, vous devez changer la langue de votre système d'exploitation et redémarrer le navigateur. C'est ne pas aussi effrayant que cela puisse paraître. Lors de mes tests, je craignais que tout mon système d'exploitation ne change immédiatement. Mais lors de mes tests, j'ai pu changer de langue, redémarrer mon navigateur et voir le changement. J'ai vite changé de retour. Les fonctions de formatage Intl vous permettent de remplacer les paramètres régionaux actuels et d’en passer un à la place..

J'ai modifié l'application pour permettre à l'utilisateur final de spécifier une langue via un menu déroulant. Voici la modification apportée au HTML. (Cette modification peut être trouvée dans test3.html)

Les langues que j'ai choisies étaient plutôt arbitraires. Next - J'ai mis à jour le code de mon application pour écouter les modifications apportées à cette liste déroulante et vérifier les paramètres régionaux souhaités lors du formatage..

Listing 3: app3.js:

function numberFormat (n) if (window.Intl) var langue = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; var formatter = new window.Intl.NumberFormat (lang); renvoyer formatter.format (n);  else return n;  function getStats () $ .getJSON ("stats.json"). done (fonction (s) // itérer sur les statistiques et ajouter à la table pour (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(); ); 

En commençant par le bas - notez que j'ai ajouté un gestionnaire d'événements simple pour les modifications du menu déroulant. Lorsqu'un changement est détecté, la table est vidée et la fonction obtenir des statistiques est exécuté. Cette nouvelle fonction résume simplement le code AJAX utilisé précédemment. Le vrai changement est maintenant dans Format de nombre. Je vérifie la langue sélectionnée et si l’une d’elles est choisie, nous la transmettons comme paramètre régional au Format de nombre constructeur. Notez que si quelque chose n'a pas été choisi, nous avons par défaut navigator.language. Cela nous donne maintenant un moyen de tester rapidement différents paramètres régionaux et de voir comment ils rendent les nombres..

Ajout du formatage de date

Le moment est venu de s’occuper de l’autre colonne de données - les chiffres. J'ai suivi le même style qu'auparavant et ajouté un appel à une nouvelle fonction, format de date.

$ table.append ("" + dateFormat (s [i] .date) + "" + nombreFormat (s [i] .views) + "");

Et voici format de date (Vous pouvez trouver le code dans app4.js, qui est utilisé par test4.html):

function dateFormat (n) // Utilisé pour l'affichage de la date var opts = ; opts.day = "numérique"; opts.weekday = "long"; opts.year = "numérique"; opts.month = "long"; if (window.Intl) var langue = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; var formatter = nouvelle fenêtre.Intl.DateTimeFormat (lang, opts); n = nouvelle date (n); renvoyer formatter.format (n);  else return n;  

Ceci est très similaire au formatage des nombres, sauf que cette fois, nous passons explicitement certaines options lors de la création du formateur. Les options spécifient quels champs sont visibles dans la date, ainsi que leur apparence. Chaque partie d'une date peut être affichée ou non, et chacune a des options différentes. Les options comprennent:

  • jour de la semaine
  • ère
  • année
  • mois
  • journée
  • heure
  • minute
  • seconde
  • timeZoneName

Pour une liste complète des valeurs que vous pouvez utiliser, voir la documentation MDN pour plus de détails. DateTimeFormat, mais à titre d'exemple, les mois peuvent être affichés sous forme de nombre ou sous différentes formes textuelles. Alors qu'est-ce que cela crée? Voici la version anglaise:

Et le voici en français:

Vous vous demandez peut-être quelle est la localisation de chaque champ? Autant que je sache, vous n’avez aucun contrôle sur cela. Vous pouvez bien sûr créer plusieurs outils de formatage, puis les combiner, mais l'utilisation d'un seul outil de formatage permet de gérer la disposition des champs en fonction de la logique interne. Si vous désactivez le jour du mois, par exemple, voici ce que vous obtenez: avril 2013 lundi. Pourquoi? Honnêtement je n'ai aucune idée.

Enfin - notez que vous devez transmettre une valeur de date, pas une chaîne, au formateur. Vous pouvez voir où j'utilise le constructeur de date dans le formateur pour analyser ma date sous forme de chaîne. Ceci est - un peu lâche - alors gardez cela à l'esprit lorsque vous utilisez cette fonctionnalité.

Montre moi l'argent

Le formatage de la devise n'est pas un objet séparé, mais plutôt une utilisation facultative du formateur de nombres. Pour la prochaine démo, nous avons créé un nouveau fichier de données, stats2.json, et ajouté une colonne "ventes" à nos données. Voici un échantillon:

"date": "01/04/2013", "vues": 938213, "ventes": 3890.21, "date": "04/02/2013", "vues": 238213, "ventes": 9890.10 

La colonne a été ajoutée au HTML (test5.html), ajouté au sein de JavaScript itérant sur les lignes de données (voir app5.js), et passé à une nouvelle fonction appelée currencyFormat. Regardons ça.

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

L'affichage de nombres en tant que devises nécessite deux valeurs facultatives. Tout d'abord, un style de "devise", puis le type de devise. D'autres options (comme comment afficher le nom de la devise) existent également. Voici la partie qui peut vous faire trébucher. Vous doit spécifier le type de devise. 

Vous vous demandez peut-être comment puis-je déterminer le type de devise pour toutes les valeurs possibles? Les valeurs possibles sont basées sur une spec (http://www.currency-iso.org/fr/home/tables/table-a1.html) et en théorie, vous pouvez analyser leur code XML, mais vous ne voulez pas le faire. La raison en est assez évidente mais je peux dire honnêtement que j’ai aussi oublié au départ. Vous ne souhaitez pas simplement afficher à nouveau un numéro particulier dans une devise spécifique à l'environnement local. Pourquoi? Parce que dix dollars américains est certainement ne pas le même que dix dollars en pesos. C'est assez évident et j'espère que je suis la seule personne à oublier que.

En utilisant le code ci-dessus, nous pouvons voir les résultats suivants dans les paramètres régionaux français. Notez que les chiffres sont formatés correctement pour les paramètres régionaux et que le symbole monétaire est placé après le nombre..

Tri avec collator

Pour notre dernier exemple, nous allons regarder le Collateur constructeur. Les assembleurs vous permettent de gérer le tri du texte. Alors que certaines langues suivent un système simple de commande de A à Z, d'autres langues ont des règles différentes. Et bien sûr, les choses deviennent encore plus intéressantes lorsque vous commencez à ajouter des accents. Pouvez-vous dire avec certitude si ä vient après? Je sais que je ne peux pas. Le constructeur du collateur prend un certain nombre d'arguments pour l'aider à spécifier exactement comment il doit être trié, mais la valeur par défaut fonctionnera probablement bien pour vous..

Pour cet exemple, nous avons créé une démo entièrement nouvelle, mais similaire aux exemples précédents. Dans test6.html, vous pouvez voir une nouvelle table, pour Étudiants. Notre nouveau code chargera un paquet d'étudiants JSON, puis les triera sur le client. Les données JSON sont simplement un tableau de noms, je ne montrerai donc pas d'extrait. Regardons la logique de l'application.

Listing 4: app6.js:

fonction trieur (x, y) if (window.Intl) var langue = $ ("# langDropdown"). val (); if (lang === "") lang = navigator.language; retourner window.Intl.Collator (lang) .compare (x, y);  else return x.localeCompare (y);  function getStudents () $ .getJSON ("students.json"). done (function (s) // itérer sur les statistiques et ajouter à la table s.sort (trieur); for (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(); ); 

Comme je l’ai dit, ce code est assez similaire aux exemples précédents, alors concentrez-vous sur obtenir des étudiants premier. La ligne cruciale ici est: s.sort (trieur). Nous utilisons la fonction intégrée permettant aux tableaux d'effectuer un tri via une fonction personnalisée. Cette fonction sera passé deux choses à comparer et doit retourner -1, 0, ou 1 pour représenter comment les deux éléments doivent être triés. Maintenant, regardons trieur.

Si nous avons un Intl objet, nous créons un nouveau Collateur (et encore une fois, nous vous permettons de passer dans une locale) puis nous courons le comparer une fonction. C'est tout. Comme je l'ai dit, il existe des options pour modifier la manière dont les choses sont triées, mais nous pouvons utiliser les valeurs par défaut. Le repli est localeCompare, qui essaiera également d’utiliser un formatage spécifique à la langue, mais supporte légèrement mieux (sous cette forme). Nous pourrions également vérifier ce soutien et ajouter une solution de secours supplémentaire pour vraiment bon soutien, mais je vais laisser cela pour vous, comme un exercice.

Nous avons également modifié le frontal pour utiliser le suédois comme langue. Je l'ai fait parce que l'excellente documentation de MDN montrait que c'était un bon moyen de voir le tri en action. Voici le genre anglais de nos noms d'étudiants:

Et le voici en suédois:

Notez comment ätest est trié différemment. (Désolé, je ne pouvais pas penser à un nom commençant par ä.)

Emballer

Dans l'ensemble, le Intl la classe fournit des très des moyens simples d’ajouter à votre code un formatage spécifique aux paramètres régionaux. C'est certainement quelque chose que vous pouvez trouver maintenant, probablement dans quelques milliers de bibliothèques JavaScript différentes, mais il est bon de voir les fabricants de navigateurs ajouter un support directement dans le langage lui-même. Le manque de support iOS est une déception, mais j'espère qu'il sera bientôt ajouté.

Merci à l’excellent réseau de développeurs Mozilla pour la qualité de sa documentation Intl.