l10n
Every interface text of the apps and the console in German (default) and English, plus the helpers every screen needs: problem code texts, formatting per locale, the language choice and the fixed term table.
Kind: Flutter package, a member of the Dart workspace at the repository root
(resolution: workspace, publish_to: none). Specification: docs/spec/01-product.md
section 9; rulings D-M4-06-1 to D-M4-06-7 in docs/DECISIONS.md.
Dependencies
Allowed members (docs/spec/15-client-architecture.md, 3.1; tools/arch-check/rules.yaml): none: no arrow of the diagram leaves this package.
Every other member is out of reach; make arch fails on a dependency or an import of it.
External packages: flutter_localizations (SDK), intl (formatting), timezone (IANA time
zones for times in users.time_zone).
Further rules checked by make arch:
- no native source (rule 4).
Layout
| Path | Content |
|---|---|
l10n.yaml |
options of flutter gen-l10n (template app_en.arb, output lib/src/generated/) |
lib/l10n/app_en.arb, lib/l10n/app_de.arb |
the texts; English is the template, German the default locale |
lib/src/generated/ |
AppLocalizations, generated by flutter gen-l10n and checked in |
lib/src/problem_text.dart |
problemText: the text of a server problem code |
lib/src/formatting.dart |
L10nFormat: money, counts, percent, durations, times, relative days |
lib/src/locale_resolution.dart |
resolveAppLocale: users.locale, else the system language, else German |
lib/src/term_pair.dart, lib/src/term_table.dart |
the term table of 01 section 9 (term_table.dart is generated) |
tool/term_table.dart |
the generator of term_table.dart |
test/ |
the gates over the ARB files and the tests of the helpers |
Add a text
- Add the key to
lib/l10n/app_en.arbwith an@keyentry that has adescription(where the text appears) and, for each argument, aplaceholdersentry with itstype. Key names arelowerCamelCasewith a screen or component prefix (liveBoxStateRunning,e1ServerAddressLabel). - Add the same key to
lib/l10n/app_de.arbwith the German text and the same ICU arguments. - Use ICU for plurals and selects (
{count, plural, =1{...} other{...}}). A text that names a limit takes the value as an argument the caller fills from the configuration; never write the number into the text. - Run
flutter gen-l10nin this directory and commit the changed files inlib/src/generated/. - Widgets read texts through
AppLocalizations.of(context), never as literals. Agent content is never translated.
No en dash (U+2013), no em dash (U+2014) and no emoji in a text; use a hyphen or rephrase.
Gates
test/completeness_test.dart: every key in both files, the same ICU arguments, the same placeholder types, a description for every template key, no empty message.test/arb_lint_test.dart: no dash and no emoji (UnicodeExtended_Pictographic, regional indicators, U+FE0F) in a message; no dash in a description.test/term_table_test.dart:lib/src/term_table.dartequals the table of 01 section 9, and an English message that uses an English term of the table has the German term of the same row in its German message. Exceptions need a reason in the test'sexceptionsmap.test/problem_text_test.dart: every code ofx-problem-codesindocs/api/openapi.yamlhas its own text.make codegen-check(tools/ci/l10n_check.py):flutter gen-l10nin a temporary copy fails on an untranslated message and on a checked-inlib/src/generated/that differs from the fresh generation.
Term table
The table between the language-check markers of 01 section 9 is the source. After a change
there, run dart run tool/term_table.dart in this directory and commit
lib/src/term_table.dart. A row with alternatives ("Forum, Beitrag" and "Forum, Post") gives
one pair per alternative; a parenthesis in the German cell is a note.
Problem codes
problemText(l, code, reason: reason) maps every code of x-problem-codes to its message
problem<Code>; a reason that 07 names selects problem<Code><Reason>. Any other code gives
problemFallback with the code, so a code the app does not know yet stays visible. A new code
in docs/api/openapi.yaml needs its message in both ARB files and a case in
lib/src/problem_text.dart in the same change, or test/problem_text_test.dart fails.
Formatting
L10nFormat(locale) formats per app locale: money(1.84, 'USD') is 1,84 USD in German and
USD 1.84 in English, with a non-breaking space; elapsed is the running clock (4:12),
durationShort the finished duration (28 min, 2 h 5 min); time and relativeDay take
the IANA time zone of the person and, for relativeDay, the current time from the caller.
Run from the repository root: make lint test coverage arch codegen-check COMPONENTS=apps. The
API pages come from make docs (Dart API reference).
Libraries
- l10n
- Every interface text of the apps and the console in German (default) and English.