Writing strings
Interface text goes through tr, with the English text itself as the key, as
in gettext:
Text::new(tr("Wi-Fi Is Off"))
Values stay out of the sentence, so a translator can move them:
trf("{} of {} free", &[free.as_str(), total.as_str()])
Without a translation, the English text is shown. Nothing breaks when a string is missing; it is only not translated yet.
Catalogs
A catalog is a JSON object, one per language, in the applet’s locales/
folder:
{
"Wi-Fi Is Off": "Wi-Fi выключен",
"{} of {} free": "Свободно {} из {}"
}
The applet embeds its catalogs and registers them once, before run:
use nirvana_protocol::{i18n, prelude::*};
fn main() {
i18n::init(&[("ru", include_str!("../locales/ru.json"))]);
run(|_handle| MyApplet::new());
}
The window’s title is translated in the registry (titles), since the runtime
needs it before the applet has said anything.
Which language
The person’s choice in Settings > Language (~/.config/etyde/locale),
otherwise the session’s locale (LC_ALL, LC_MESSAGES, LANG).
i18n::language() gives the code in use, for the rare thing that depends on
it (the decimal mark in the calculator).
Applets pick up a change of language while they run.
Adding a language
A language is one more catalog in each applet, registered in its i18n::init,
and one more choice in Settings > Language.
Writing well
- Title Case for titles, buttons and row titles; sentence case for descriptions.
- Name a button after what it does: “Join”, “Forget This Network”. Not “OK”.
- An ellipsis (…) marks an action that will ask for more, and a state in progress.
- Typographic quotes and apostrophes: “Home”, isn’t.
- No full stop after a label or a subtitle of one line; full sentences in footers and messages end with one.
- A translation follows the conventions of its own language: Russian uses «ёлочки» and sentence case for titles.