Passer au contenu principal
Un bot qui parle plusieurs langues ne met pas un if sur la langue dans chaque fichier : il déclare ses textes une fois par langue, et chaque fonction reçoit t, qui choisit le bon. Cette page donne deux langues à votre bot, et fait répondre /ping avec t('pong').

Une déclaration par langue

Une langue se déclare avec language() : locale dit laquelle, texts contient les textes du bot par clé. Créez un fichier par langue dans src/messages/ :
src/messages/en-US.ts
src/messages/fr.ts
  • locale est la langue, comme l’écrit Discord : 'en-US', 'en-GB', 'fr', 'de', 'es-ES', 'pt-BR', 'ja'… Un mot que Discord ne connaît pas est souligné, et refusé quand le fichier se charge, avec la liste.
  • default: true marque la langue utilisée quand celle demandée n’est pas là. Exactement un fichier le dit : avec chapterjs dev lancé, deux fichiers qui le disent sont soulignés tous les deux dans l’éditeur.
  • Un paramètre est un nom entre accolades : {name}, {count}. Il prend un texte ou un nombre, et un nombre est écrit comme la langue écrit les nombres (1,234 en anglais, 1 234 en français).
  • Un pluriel a une forme par quantité (one, other, et zero, two, few, many pour les langues qui en ont besoin). count choisit la forme selon les règles de la langue.
La langue par défaut a tous les textes, et les autres langues peuvent n’en avoir qu’une partie : ce qui manque vient de la langue par défaut. Un texte qu’une autre langue a mais que la langue par défaut n’a pas, ou un {name} devenu {nom}, est signalé sur ce fichier, et cette langue est mise de côté jusqu’à ce qu’elle corresponde.

t : un texte dans la bonne langue

Chaque fonction de votre projet (commandes, événements, boutons, formulaires, tâches) reçoit t. Changez l’accueil du chapitre sur les événements pour l’utiliser :
src/events/hello.ts
Tapez t(' dans votre éditeur : il propose pong, welcome, next, members, les clés de la langue par défaut. Choisissez welcome, et le second argument demande name et count : les paramètres du texte, lus dans le fichier. Oubliez count, et la ligne est soulignée. Les types viennent du fichier de langue lui-même, à chaque frappe, sans rien générer à partir de son contenu. Un pluriel prend son count de la même façon :
src/commands/members.ts

Quelle langue parle t

Voici la partie subtile, et la raison pour laquelle t existe plutôt qu’un if (interaction.locale === 'fr'). Un message est envoyé une fois, et tout le monde dans le salon lit le même texte : Discord ne le traduit pas pour chaque lecteur. Alors t parle la langue de ceux qui liront ce que vous envoyez, pas de la personne qui a utilisé la commande : Discord ne connaît la langue que d’un serveur Communauté (un réglage du serveur). Ailleurs, il dit en-US quelle que soit la langue des membres, donc un message public y utilise votre langue par défaut. Un bot dans une seule langue met cette langue par défaut et n’y pense plus jamais ; un bot dans plusieurs suit les grands serveurs, qui règlent la leur. t.locale dit quelle langue a été prise, et t.in('fr', 'welcome', { ... }) donne un texte dans une autre langue, pour un message destiné à quelqu’un d’autre. Quand la langue exacte n’est pas dans vos fichiers, t prend la plus proche (en-GB lit les textes en-US), et celle par défaut sinon.
t est donné à votre fonction avant qu’elle ne tourne, pour le public que déclare le fichier. Une commande qui n’est pas ephemeral mais qui répond avec ephemeral: true au moment de l’appel garde la langue du serveur dans cette réponse. Quand les réponses d’une commande sont pour la personne, mettez ephemeral: true sur la commande : t parle alors sa langue, et c’est aussi la valeur par défaut de ses réponses.

Les textes des boutons, menus et formulaires

Une étiquette s’écrit dans le fichier du composant, où il n’y a pas encore de t : le message n’est pas envoyé. Pour la traduire, faites-en une fonction de t et des données ; elle tourne au moment de l’envoi du message, pour qui le lira :
src/components/next-page.ts
Cela fonctionne pour le label d’un bouton, le placeholder d’un menu et ses options, le title d’un formulaire et les textes de ses champs.

Ce que le bot répond de lui-même

Quand le bot ne peut pas lancer ce qui a été demandé (une commande utilisée au mauvais endroit, un bouton d’un vieux message, un run qui a levé une erreur), il répond de lui-même, en anglais. Ces phrases se traduisent dans framework, avec les mots pour une commande, un bouton, un menu et un formulaire, que remplace {what} :
src/messages/fr.ts
Une phrase reçoit sa réponse dans la langue de la personne ; une phrase qu’un fichier ne traduit pas reste en anglais. Chaque phrase, avec son texte anglais, est dans la Référence.

Les descriptions des commandes

Ce que Discord affiche d’une commande avant qu’elle ne soit utilisée (son nom, sa description, ses options) est enregistré, pas envoyé par le bot, donc cela ne peut pas passer par t. C’est la seule chose traduite par des données. Une commande peut laisser description hors de son fichier et l’avoir dans les fichiers de langue à la place, par le nom de la commande :
src/messages/en-US.ts
La langue par défaut donne la description que tout le monde voit ; les autres langues donnent leurs traductions (name aussi, quand la commande doit avoir un autre nom dans cette langue). Une commande a ses textes à un seul endroit : avec description dans son fichier, un fichier de langue qui la mentionne est une erreur ; sans elle, le fichier ne doit pas avoir de locales. Déplacez-y aussi la description de /ping, et retirez-la de son fichier : les modèles tickets, music, community et moderation le font pour chaque commande.

Points d’attention

  • Les clés sont typées d’après le fichier par défaut. Ajoutez un texte là d’abord, puis dans les autres ; l’éditeur et le chargeur le vérifient tous les deux.
  • Les accolades écrites telles quelles sont doublées : '{{name}}' affiche {name}.
  • La langue d’un serveur est en-US sauf si c’est un serveur Communauté. Ne soyez pas surpris qu’un message public sur un serveur français sorte dans la langue par défaut.
  • Sans langue, il n’y a pas de t : il n’existe ni dans les types ni à l’exécution. Passez-vous des fichiers de langue si votre bot parle une seule langue et que vous préférez des textes simples.

Récapitulatif

  • language({ locale, texts }) contient les textes d’une langue par clé ; l’une d’elles est default: true.
  • t('clé', { paramètres }) donne le texte dans la langue de qui le lira ; l’éditeur vérifie les clés et les paramètres.
  • L’étiquette d’un composant est une fonction de t ; les phrases du bot vont dans framework ; les descriptions des commandes dans commands.

Organiser un projet qui grandit

Partager du code, stocker des données, et garder les fichiers courts.

Guide : Messages traduits

La même chose, en bref.