Notre sujet de la semaine concerne la configuration nécessaire afin d’utiliser des formats personnalisés avec react-intl.

React-intl est un paquet développé pour React par Yahoo, et fait partie du projet FormatJS, qui vise à utiliser autant que possible — et à y ajouter — les standards existants pour tout ce qui concerne l’internationalisation.

Dans nos applications et projets, chez BesLogic, nous rédigeons habituellement notre contenu en français et en anglais, ce qui fait que l’internationalisation est très importante pour nous. Vous pouvez donc vous attendre à voir d’autres articles parler de ce sujet dans le futur.

En React, react-intl fournit à l’équipe de développement des contrôles React afin d’exposer son interface d’internationalisation. Dans le cas d’un nombre, par exemple, l’élément FormattedNumber est celui tout désigné pour afficher un nombre selon la culture de l’utilisateur ou l’utilisatrice. react-intl s’occupe alors de choisir, entre autres, le format des décimales et le groupement des chiffres, par exemple, selon cette culture.

Voici à quoi peut ressembler une utilisation de base de ce contrôle :

En français, ce résultat ressemblerait à «1 234 567 890», tandis qu’en anglais, où on utilise une virgule pour séparer les nombres, le résultat serait plutôt «1,234,567,890».

Supposons que vous souhaitiez désactiver le regroupement des nombres, pour quelque raison. C’est l’exemple que j’utiliserai dans cet article, puisqu’il est plutôt simple, mais reflète quand même un cas d’utilisation réel.

Si tout ce que vous souhaitez faire est d’afficher un nombre, le code requis pour arriver à ce résultat est assez simple. Les options de formats que reconnait react-intl sont les mêmes que celles de l’interface standard de JavaScript, Intl, qui contient justement une propriété «useGrouping» qui nous permet de faire ce que l’on veut. Dans ce cas, l’élément React fourni reconnait directement cette option :

Avec ce changement, on obtient le résultat souhaité : «1234567890».

Cet exemple fonctionne bien pour des cas très simple, mais comment fait-on si l’on souhaite afficher ce nombre en plein milieu d’une chaine traductible? On pourrait insérer notre élément FormattedNumber entre nos deux morceaux de chaines, mais cela aurait pour effet de fixer ce nombre toujours au même endroit dans la phrase, alors que, tout dépendant du langage, ce nombre pourrait être appelé à se trouver à une autre position dans la phrase.

L’élément FormattedMessage nous permet de spécifier un paramètre variable dans notre chaine traductible, qui pourra donc être déplacé par l’équipe de traduction selon les besoins du langage, mais il n’est pas possible de spécifier l’option de format directement dans le paramètre ou à l’élément lui-même :

En effet, même si l’on ajoutait un attribut «useGrouping» à notre élément, il serait tout simplement ignoré. Lorsqu’un format existant correspond déjà à nos besoins, on le passe comme troisième paramètre à notre variable de chaine, mais dans notre cas, aucun des ensembles d’options préexistant ne répond à notre besoin!

defaultMessage="We want to have {howMany, number, ???} things!"

Nous allons donc devoir écrire notre propre format de nombre, et l’envoyer à notre IntlProvider, afin que ce format devienne disponible dans nos Formatters. Le format lui-même est très simple à créer, puisqu’il s’agit d’un objet JavaScript standard. Il suffit de créer un objet avec nos options de formats et de l’assigner à la catégorie de formats correspondante. Enfin, cet objet peut-être passé en attribut au IntlProvider, et le tour est joué!

Une fois notre format enregistré auprès du IntlProvider, il ne reste plus qu’à l’utiliser dans notre message à traduire :

J’espère que cet article vous aura permis d’éclairer un peu plus la façon dont on utilise des formats personnalisés avec react-intl!

Chaque vendredi, un article comme celui-ci devrait être publié. Les sujets varient de semaine en semaine, et ne sont pas toujours à propos de React ou d’internationalisation.

N’oubliez donc pas de vous abonner à ce blogue! On se retrouve la semaine prochaine!