Trouver les clés manquantes dans les fichiers ARB d'une app Flutter
Mis à jour le · GLabs325
Une clé ajoutée en anglais et oubliée en allemand, un placeholder renommé dans une seule langue : ces erreurs passent la compilation et finissent devant vos utilisateurs. Voici comment les repérer avant la release.
Rappel : comment sont organisés les fichiers ARB
Avec flutter gen-l10n, chaque langue a son fichier (app_en.arb, app_fr.arb…). Le fichier de modèle, défini par template-arb-file dans l10n.yaml, fait référence : il contient toutes les clés et leurs métadonnées @cle (description, placeholders).
{
"cartCount": "{count, plural, =0{Empty cart} =1{1 item} other{{count} items}}",
"@cartCount": {
"placeholders": { "count": { "type": "int" } }
}
}
1. Laisser Flutter lister les messages non traduits
Ajoutez l'option untranslated-messages-file dans l10n.yaml :
arb-dir: lib/l10n
template-arb-file: app_en.arb
untranslated-messages-file: untranslated.json
À chaque génération, Flutter écrit dans ce fichier, langue par langue, les clés du modèle absentes des autres fichiers. C'est le contrôle le plus simple à mettre en place ; vérifiez que le fichier est vide (ou ne contient que {}) avant de publier.
2. Comparer les clés avec un petit script Dart
Pour un contrôle en CI qui échoue clairement, un script suffit :
import 'dart:convert';
import 'dart:io';
void main() {
final dir = Directory('lib/l10n');
final template = _keys(File('lib/l10n/app_en.arb'));
var failed = false;
for (final file in dir.listSync().whereType<File>()) {
if (!file.path.endsWith('.arb')) continue;
final missing = template.difference(_keys(file));
if (missing.isNotEmpty) {
failed = true;
print('${file.path}: ${missing.join(', ')}');
}
}
if (failed) exit(1);
}
Set<String> _keys(File f) => (jsonDecode(f.readAsStringSync()) as Map<String, dynamic>)
.keys
.where((k) => !k.startsWith('@'))
.toSet();
Les clés qui commencent par @ sont des métadonnées ; on les exclut de la comparaison.
3. Contrôler les placeholders
Une clé présente partout peut quand même casser : si la traduction française utilise {nombre} alors que le modèle déclare {count}, gen-l10n ajoute nombre comme paramètre supplémentaire dans toutes les langues, et les appels existants ne compilent plus. À l'inverse, une traduction qui oublie simplement un placeholder passe sans aucun avertissement (détails dans le guide sur les pluriels et placeholders ICU). Pour chaque clé, comparez l'ensemble des noms entre accolades avec ceux déclarés dans @cle.placeholders. Attention aux messages ICU (plural, select) : les mots-clés comme other ne sont pas des placeholders.
4. Surveiller aussi les valeurs vides
Certains pipelines de traduction créent la clé avec une valeur vide en attendant la traduction. Elle n'apparaît donc pas comme « manquante » ; ajoutez un contrôle qui signale les chaînes vides dans les langues autres que le modèle.
Checklist avant une release
- Le fichier des messages non traduits est vide.
- Toutes les langues ont les mêmes clés que le modèle.
- Les placeholders correspondent, clé par clé.
- Aucune valeur vide hors du modèle.
- Les messages longs ont été vérifiés à l'écran dans les langues les plus verbeuses (allemand, par exemple).
Questions fréquentes
Flutter signale-t-il les traductions manquantes ?
Oui, si vous ajoutez untranslated-messages-file dans l10n.yaml : flutter gen-l10n y liste les clés du modèle absentes de chaque langue. Sans cette option, il ne fait qu'afficher un avertissement récapitulatif.
Faut-il copier les métadonnées @cle dans chaque langue ?
Non. Les métadonnées (description, placeholders) sont lues depuis le fichier de modèle ; les autres fichiers ont seulement besoin des traductions.
Comment éviter les placeholders mal nommés ?
Comparez, pour chaque clé, les noms entre accolades de la traduction avec ceux déclarés dans le modèle, et faites échouer la CI en cas d'écart.