Ontbrekende sleutels vinden in de ARB-bestanden van een Flutter-app

Bijgewerkt op · LocalePilot

Een sleutel die in het Engels is toegevoegd en in het Duits vergeten, een placeholder die in maar één taal is hernoemd: deze fouten compileren prima en komen bij je gebruikers terecht. Zo vang je ze vóór de release.

Controleer je ARB-bestanden direct in je browser: gratis, zonder account, er wordt niets geüpload.

Kort herhaald: hoe ARB-bestanden zijn opgebouwd

Met flutter gen-l10n heeft elke taal een eigen bestand (app_en.arb, app_nl.arb…). Het templatebestand, ingesteld met template-arb-file in l10n.yaml, is de referentie: het bevat elke sleutel en de bijbehorende @key-metadata (beschrijving, placeholders).

{
  "cartCount": "{count, plural, =0{Empty cart} =1{1 item} other{{count} items}}",
  "@cartCount": {
    "placeholders": { "count": { "type": "int" } }
  }
}

1. Laat Flutter onvertaalde berichten opsommen

Voeg de optie untranslated-messages-file toe aan l10n.yaml:

arb-dir: lib/l10n
template-arb-file: app_en.arb
untranslated-messages-file: untranslated.json

Bij elke generatie schrijft Flutter de templatesleutels die per taal ontbreken naar dat bestand. Het is de eenvoudigste controle om in te stellen; zorg dat het bestand leeg is (of alleen {} bevat) voordat je uitbrengt.

2. Vergelijk sleutels met een klein Dart-script

Voor een CI-controle die duidelijk faalt, volstaat een script:

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();

Sleutels die met @ beginnen zijn metadata en worden dus niet meegenomen in de vergelijking.

3. Controleer placeholders

Een sleutel die overal aanwezig is, kan nog steeds stukgaan: gebruikt de Franse vertaling {nombre} terwijl de template {count} declareert, dan voegt gen-l10n nombre toe als extra parameter in elke locale, en bestaande aanroepen compileren niet meer. Omgekeerd komt een vertaling die een placeholder gewoon laat vallen er zonder enige waarschuwing door (details in de handleiding over ICU-meervoud en placeholders). Vergelijk per sleutel de namen tussen accolades met die in @key.placeholders. Let op ICU-berichten (plural, select): trefwoorden als other zijn geen placeholders.

4. Let ook op lege waarden

Sommige vertaalpijplijnen maken de sleutel aan met een lege waarde tot hij vertaald is. Die verschijnt niet als "ontbrekend", dus voeg een controle toe die lege teksten meldt in elke taal behalve de template.

Checklist vóór de release

  • Het bestand met onvertaalde berichten is leeg.
  • Elke taal heeft dezelfde sleutels als de template.
  • Placeholders komen overeen, sleutel voor sleutel.
  • Geen lege waarden buiten de template.
  • Lange berichten zijn op het scherm gecontroleerd in de langste talen (bijvoorbeeld Duits of Nederlands).

Veelgestelde vragen

Meldt Flutter ontbrekende vertalingen?

Ja, als je untranslated-messages-file aan l10n.yaml toevoegt: flutter gen-l10n zet daar de templatesleutels in die per taal ontbreken. Zonder die optie krijg je alleen een samenvattende waarschuwing.

Moet ik de @key-metadata naar elke taal kopiëren?

Nee. De metadata (beschrijving, placeholders) wordt uit het templatebestand gelezen; de andere bestanden hebben alleen de vertalingen nodig.

Hoe voorkom ik verkeerd benoemde placeholders?

Vergelijk per sleutel de namen tussen accolades in de vertaling met die in de template, en laat CI falen als ze verschillen.