3.3 KiB
Translating FigCraft
FigCraft's interface strings live in one TOML catalog per language in
crates/ui-egui/locales/. The build bakes every catalog into the
binary (desktop and web); nothing is read at run time. Preferences ▸ Language picks the language
(System follows the OS, or the browser on the web) and the interface switches at once. pref.language {language} does the same from the CLI, MCP and the control channel.
The catalogs
en.tomllists every key. A key is the English text as the code writes it, so the code stays readable:tr("Fill"),trf("Delete {name}?", &[("name", &name)]),trn("{n} layers", count, &[]). Values equal their keys except plurals, which give both forms:"{n} layers" = { one = "{n} layer", other = "{n} layers" }.es.tomland other languages translate the same keys under[ui], plus command labels by command id under[commands](the Actions palette, the shortcuts panel and the menus) and, under[menu], the few menu items the main menu words differently from the command (the Select matching submenu's "Fill" for "Select same fill"). Command ids, the CLI, MCP and control-channel output stay English.[meta] nameis the language's own name (the picker shows it untranslated);[meta] statusmarks a draft (the Preferences window says so).
A key a catalog lacks shows its English text, so a partial catalog is safe to ship.
Adding a language
-
Copy
crates/ui-egui/locales/es.tomlto<code>.toml(a BCP 47 code:fr,pt-BR,ja) and set[meta] nameandstatus = "draft — needs native review". -
Translate every value; keep the keys. Keep
{placeholders}exactly, "…" where English has it, brand names and keyboard glyphs. English labels of commands:figcraft-cli commands. -
Plurals: give
oneonly if the language has a singular form (Japanese, Korean and Chinese give onlyother).trnpicksonefor a count of 1; a language with other rules (French: 0 and 1) needs its rule inplural_oneincrates/ui-egui/src/i18n.rs. -
To require full coverage, add the code to
COMPLETEincrates/ui-egui/src/i18n_tests.rs. -
Run the check and look at the panels in the app (longer words must fit the right panel):
cargo test -p figcraft-ui-egui i18n
The check fails on keys the code uses that en.toml lacks (it prints the lines to paste), keys no
code uses, unknown command ids, placeholders that don't match English, and, for complete languages,
anything untranslated. Machine-drafted catalogs stay marked as drafts until a native speaker has
reviewed them.
Adding strings in code
Wrap every string a user sees or a screen reader hears: tr for plain text, trf for {named}
placeholders, trn for counts, tr_noop for literals in const tables that are looked up later
with tr(label). The key must be a string literal as the first argument (the check reads the
source). Don't wrap ids, command ids, JSON, log messages, file extensions or document content. Then
add the key to en.toml and to each complete language.
Labels from the engine and document crates (tool names, blend modes, easing curves…) are looked up
at display with tr(x.label()); they are listed in dynamic_labels in i18n_tests.rs.