Lokalisatie (i18n)

Finch heeft een ingebouwd i18n-systeem met ondersteuning voor meerdere talen. Taalstrings kunnen worden opgeslagen in JSON-bestanden of rechtstreeks in Dart worden gedefinieerd.

Configuratie

Stel de taalopties in via FinchConfigs:

FinchConfigs configs = FinchConfigs(
  // Pad naar de map met taal-JSON-bestanden
  languagePath: pathTo(env.get('LANGUAGE_PATH', './lib/languages')),

  // Gebruik JSON-bestanden (LanguageSource.json) of Dart-maps (LanguageSource.dart)
  languageSource: LanguageSource.json,

  // Als je LanguageSource.dart gebruikt, geef de map hier op:
  // dartLanguages: languageDart,
);

Optie 1: JSON-bestanden

Maak per taal één JSON-bestand aan in je languagePath-map. De bestandsnaam is de taalcode:

lib/languages/en.json

{
  "dir": "ltr",
  "logo.title": "My App",
  "greeting": "Hello, World!",
  "example.params": "My name is {name}, my age is {age}",
  "example.params.arr": "My name is {0}, my age is {1}"
}

lib/languages/fa.json

{
  "dir": "rtl",
  "logo.title": "برنامه من",
  "greeting": "سلام دنیا!",
  "example.params": "نام من {name} است، سن من {age} سال است"
}

De dir-sleutel (ltr / rtl) is hier een gewone vertaalsleutel zoals elke andere — lees deze in een sjabloon met {{ $t('dir') }} (zoals het voorbeeld in Templates doet), niet met {{ $e.dir }}. $e.dir zoekt in plaats daarvan een anders genoemde sleutel op — zie Template Events voor dat onderscheid.

Optie 2: Dart-map

Definieer talen als een Dart-Map<String, Map<String, String>> en verwijs er in FinchConfigs naar:

// lib/languages/language_dart.g.dart (of een andere naam)
const languageDart = <String, Map<String, String>>{
  'en': {
    'dir': 'ltr',
    'logo.title': 'My App',
    'greeting': 'Hello, World!',
    'example.params': 'My name is {name}, my age is {age}',
  },
  'fa': {
    'dir': 'rtl',
    'logo.title': 'برنامه من',
    'greeting': 'سلام دنیا!',
    'example.params': 'نام من {name} است، سن من {age} سال است',
  },
};
FinchConfigs configs = FinchConfigs(
  languageSource: LanguageSource.dart,
  dartLanguages: languageDart,
);

De finch serve-watcher kan JSON-bestanden automatisch omzetten naar een Dart-map. Het gegenereerde bestand wordt weggeschreven naar language_dart.g.dart.

Vertalen in controllers

Gebruik de .tr-extensie op elke sleutel-string. .write() rendert de uiteindelijke vertaalde string:

// Eenvoudige vertaling
String text = 'logo.title'.tr.write();

// Met benoemde parameters
String text = 'example.params'.tr.write({'name': 'Alice', 'age': 30});

// Met positionele parameters (array) — er is geen gewone `.writeArr()`;
// geef de huidige taal expliciet mee aan `writeByLangArr`
String text = 'example.params.arr'.tr.writeByLangArr(rq.getLanguage(), ['Alice', 30]);

Geef vertaalde strings door aan sjablonen:

rq.addParams({
  'greeting': 'greeting'.tr.write(),
  'userLine': 'example.params'.tr.write({'name': 'Alice', 'age': 30}),
});
return rq.renderView(path: 'pages/home');

Vertalen in sjablonen

Gebruik {{ $t('key') }} voor inline vertaling:

<h1>{{ $t('logo.title') }}</h1>
<p>{{ $t('example.params', {'name': user.name, 'age': user.age}) }}</p>
<p>{{ $t('example.params.arr', ['Alice', 30]) }}</p>

Taal wisselen

De taal wordt in deze volgorde bepaald:

  1. Eerste padsegment, als dit overeenkomt met een bekende taalcode (bijv. /fa/home)
  2. lang-datafield op API-endpoints
  3. language-cookie
  4. language-sessiesleutel
  5. Standaardwaarde uit de instellingen

Welke waarde ook wordt herleid, deze wordt altijd gevalideerd tegen FinchConfigs.languages; als het niet een van de geconfigureerde talen is (bijvoorbeeld een ongeldige of verouderde cookie), valt Finch terug op 'en'.

Taal wijzigen vanuit een controller:

rq.changeLanguege('fa');

Genereer in een sjabloon een URL die van taal wisselt:

<a href="{{ $e.urlToLanguage('fa') }}">فارسی</a>
<a href="{{ $e.urlToLanguage('en') }}">English</a>

Beschikbare talen in sjablonen

{% for lang in $e.langs %}
  <a href="{{ $e.urlToLanguage(lang.code) }}">{{ lang.label }}</a>
{% endfor %}

Elke entry: { code: 'en', label: 'English', contry: 'United States' } — let op: de velden label/contry zijn leeg/onopgelost tenzij je de sleutels language.<code>_label/language.<code>_contry hebt toegevoegd die worden beschreven in Template Events.

TString — vertaalobjecten

TString wrapt een sleutel en laat je de vertaling uitstellen:

var ts = TString('example.params');
rq.addParam('exampleTString', ts.write());

// Of met de .tr-shorthand:
rq.addParam('examplePathString', 'example.path'.tr.write());

Positionele (array)parameters

In plaats van benoemde {name}-placeholders kan een vertaalstring positionele {0}, {1}, … placeholders gebruiken:

{
  "example.params.arr": "My name is {0}, my age is {1}"
}

Vul ze in vanuit een sjabloon met een lijstargument aan $t:

<p>{{ $t('example.params.arr', ['Alexandre', 30]) }}</p>

Of vanuit Dart, met writeByLangArr (er is geen gewone .writeArr()-shorthand — zie Vertalen in controllers hierboven):

rq.renderString(text: 'example.params.arr'.tr.writeByLangArr(rq.getLanguage(), ['Alexandre', 30]));