T ToutadminДокументация

Эта страница ещё не переведена на ваш язык: она показана по-французски.

Traductions

L'interface existe en 16 langues : le français, langue de référence du produit, et les quinze langues les plus parlées. 2765 clés déclinées 16 fois, soit 44240 chaînes, dont la cohérence est tenue par les tests plutôt que par la relecture.

Les langues disponibles#

CodeLangueSens d'écriture
fr🇫🇷 Français référencegauche à droite
en🇬🇧 Englishgauche à droite
es🇪🇸 Españolgauche à droite
de🇩🇪 Deutschgauche à droite
it🇮🇹 Italianogauche à droite
pt🇵🇹 Portuguêsgauche à droite
nl🇳🇱 Nederlandsgauche à droite
pl🇵🇱 Polskigauche à droite
ru🇷🇺 Русскийgauche à droite
tr🇹🇷 Türkçegauche à droite
ar🇸🇦 العربيةdroite à gauche
hi🇮🇳 हिन्दीgauche à droite
zh🇨🇳 中文gauche à droite
ja🇯🇵 日本語gauche à droite
ko🇰🇷 한국어gauche à droite
vi🇻🇳 Tiếng Việtgauche à droite

La langue se choisit par drapeau sur l'écran de connexion — avant même d'avoir un compte — et depuis le profil une fois connecté.

Comment la langue est choisie#

Trois sources, dans cet ordre :

  1. Le choix du compte, enregistré dans le profil.
  2. Le cookie, pour un visiteur non connecté qui a cliqué un drapeau sur l'écran de connexion.
  3. L'en-tête Accept-Language du navigateur.

À défaut, le français.

Une clé absente ne casse jamais la page#

function translate(locale, key, params) {
  const dict = dictionaries[locale] || {};
  let value = dict[key];
  if (value === undefined) value = dictionaries[DEFAULT_LOCALE][key];
  if (value === undefined) return key;
  …
}

Une traduction manquante retombe sur le français ; une clé inexistante ressort telle quelle. Une traduction incomplète dégrade l'affichage, elle ne casse rien.

Les statuts se traduisent aussi#

C'est le point le moins évident du dispositif. Les statuts — Approuvée, Brouillon, En attente — sont stockés en français dans la base. C'est la valeur métier : elle sert aux contraintes CHECK du schéma, aux comparaisons du code et aux paramètres d'URL. Elle ne doit pas bouger avec la langue de l'utilisateur.

Mais ce qui s'affiche passe par le dictionnaire. Une table de correspondance associe chaque valeur stockée à une clé de traduction, et un helper st() disponible dans toutes les vues fait la conversion au moment du rendu.

function statusLabel(locale, value) {
  if (!value) return '';
  const key = STATUS_KEYS[value];
  return key ? translate(locale, key) : value;
}
Stocké en baseClé🇬🇧🇩🇪🇯🇵
Approuvéestatus.approvedApprovedGenehmigt承認済み
Brouillonstatus.draftDraftEntwurf下書き
En attentestatus.pendingPendingAusstehend保留中
Signéstatus.signedSignedUnterzeichnet署名済み

167 valeurs de statut sont couvertes, ramenées à 150 clés : les paires de genre du français (Annulé / Annulée, Refusé / Refusée) partagent une traduction, les autres langues ne faisant pas la distinction.

Un statut inconnu ressort tel quel

Une valeur absente de la table — un statut ajouté par l'exploitant, par exemple — s'affiche telle quelle plutôt que de laisser une case vide. Mieux vaut un mot français qu'un blanc.

L'arabe retourne réellement la page#

Passer dir="rtl" sur la page ne suffit pas. Le navigateur inverse le texte et l'ordre des éléments en flex, mais une marge déclarée margin-left reste à gauche : le liseré de l'onglet actif, la pastille du compte et les marges de tableau se retrouveraient du mauvais côté.

La feuille de style du produit n'emploie donc que des propriétés logiques :

Au lieu deOn écrit
border-leftborder-inline-start
padding-rightpadding-inline-end
margin-rightmargin-inline-end
text-align: lefttext-align: start
padding: 0 8px 0 4pxpadding-inline: 4px 8px

Le résultat se vérifie géométriquement plutôt qu'à l'œil : en arabe, le liseré de l'onglet actif passe de 3 px à gauche à 3 px à droite, et la barre latérale passe du bord gauche au bord droit de la fenêtre.

Ce que les tests garantissent#

Un dictionnaire de 44240 chaînes ne se relit pas. Dix-sept tests vérifient à chaque exécution de la suite :

VérificationLe défaut qu'elle attrape
Parité des clésUne langue à laquelle on a oublié d'ajouter une clé
Aucune valeur videUne chaîne laissée en blanc
Paramètres {nom} identiquesUn paramètre perdu à la traduction : la phrase s'affiche amputée, sans erreur
Écritures non latinesUne traduction oubliée se repère à ce qu'elle reste en caractères latins
Toute clé appelée existeUne faute de frappe dans un t('…')
Chaque statut pointe vers une clé existanteUne entrée de table qui ne mène nulle part
Tout statut du schéma est traduitUn statut ajouté à une contrainte CHECK sans traduction
Aucune vue n'affiche un statut brutUn <%= x.status %> qui a échappé au helper
Aucune vue ne masque le helperUne boucle forEach((t) => …) qui rend t() inappelable
Un statut inconnu ressort tel quelUne valeur absente du dictionnaire affichée en blanc plutôt qu'en français
Un même statut se traduit dans chaque langueUn statut traduit dans deux langues et oublié dans les quatorze autres
Toutes les vues compilentUn gabarit cassé par une substitution, qui ne tomberait qu'à l'ouverture de la page
Les dates suivent la langueUn 03/04 anglais lu comme le 4 mars — ou l'inverse
Le chrome partagé est traduitUn libellé en dur dans l'en-tête ou la navigation, donc visible partout
Le CSS ne fige aucun côtéUn margin-left qui casserait la mise en page arabe
Rendu de bout en boutUne page servie en allemand qui parle encore français
Bascule RTLUne page arabe qui ne passe pas en dir="rtl"
Le piège du masquage

Une boucle écrite tools.forEach((t) => …) masque le helper de traduction : à l'intérieur, t('common.edit') tente d'appeler l'objet de la boucle comme une fonction et la page tombe. Le cas s'est produit ; un test l'interdit désormais dans toutes les vues.

Où en est la couverture#

Les 89 vues du produit sont traduites, du premier écran de connexion à la dernière boîte de dialogue de confirmation. Les quatre espaces, le chrome présent sur chaque page (en-tête, compte, déconnexion, sélecteur de thème, navigation latérale), tous les statuts, le vocabulaire générique et le vocabulaire propre à chaque métier : comptabilité, paie, trésorerie, qualité, parapheur, sauvegardes, interfaces, données personnelles, parc logiciel, livraisons, événements, points individuels, conformité des tiers, alerte interne, achats, recouvrement et vie juridique.

Ce qui reste en français, et pourquoi

Trois choses, aucune n'étant du texte affiché : les paramètres d'URL du journal d'audit (&du=, &au=), l'exemple de commande curl de la documentation d'API, et un commentaire dans le script qui applique le thème avant le premier rendu. Traduire un identifiant de requête casserait le filtre ; traduire une commande la rendrait incopiable.

Deux règles tenues d'un bout à l'autre#

Les valeurs stockées ne bougent pas. Un statut est écrit en français dans la base : c'est la valeur métier, celle des contraintes CHECK, des comparaisons et des URL de filtre. Seul l'affichage passe par le dictionnaire. Les attributs value d'un <select>, les chaînes comparées dans une condition et les identifiants de filtre gardent leur libellé français — traduire la donnée aurait cassé le produit dans quinze langues sur seize.

Une phrase coupée par une donnée devient une clé paramétrée. « {count} échec(s) consécutif(s) », « Pagination par {limit} (200 au plus) et {since} », « {total} échéance(s) à 45 jours, dont {overdue} dépassée(s) » : l'ordre des mots n'est pas le même d'une langue à l'autre, et un nombre collé entre deux fragments traduits séparément ne se lit correctement nulle part.

Ajouter ou corriger une traduction#

Les dictionnaires vivent dans src/locales/, un fichier par langue, exportant un objet plat. Le français est la référence : c'est lui qui définit le jeu de clés.

module.exports = {
  'common.save': 'Enregistrer',
  'leave.available': 'Solde disponible : {days} jours',
  …
};

Pour ajouter une clé, trois règles :

  1. L'ajouter dans les 16 fichiers — le test de parité échoue sinon.
  2. Reprendre les mêmes paramètres {nom} dans chaque langue, quel que soit leur ordre dans la phrase.
  3. Écrire dans l'écriture de la langue — un test refuse une valeur restée en caractères latins pour le russe, l'arabe, le hindi, le chinois, le japonais ou le coréen. Les sigles techniques (JPEG, PNG) et la marque en sont exemptés.

Pour ajouter un statut, l'inscrire aussi dans la table STATUS_KEYS de src/i18n.js : un statut déclaré au schéma mais absent de la table fait échouer les tests plutôt que de ressortir en français chez un utilisateur étranger.

Le lexique permet de parcourir et chercher l'intégralité des 2765 clés dans les 16 langues.

Документация Toutadmin — собрана 2026-09-13. Самостоятельный сайт, независимый от программы.