Chapter 18 — Internationalization (i18n)
6 tests, no DB — rustango::i18n::Translator, Django's gettext
family in Rust. Run with cargo test --test cookbook_chapter18_i18n.
$ cargo test --test cookbook_chapter18_i18n
test result: ok. 6 passed; 0 failed; 0 ignored
Translator holds per-locale message catalogs and resolves a key with
base-language fallback (fr-CA → fr → default), {name} placeholder
substitution, and CLDR-correct pluralization. Pair it with
Accept-Language negotiation and RTL detection for a fully localized UI.
use rustango::i18n::{Locale, Translator};
let t = Translator::new(Locale::new("en"))
.add_locale(Locale::new("fr"), /* {"welcome": "Bienvenue, {name} !"} */);
t.translate("fr", "welcome", &[("name", "Ada")]); // "Bienvenue, Ada !"
- §18.140 —
gettextlookup + missing-key / unknown-locale / regional (fr-CA→fr) fallback. →gettext_lookup_and_fallback - §18.141 —
{name}placeholder substitution viatranslate. →placeholder_substitution - §18.142 —
ngettext(singular/plural) + CLDRplural_category+ per-categorytranslate_plural(Polish one/few/many). →pluralization - §18.143 —
Accept-Languagenegotiation picks the best supported language (negotiate_language). →accept_language_negotiation - §18.144 — RTL detection +
text_direction(dir="rtl"). →rtl_and_direction - §18.145 — the
{% translate %}Tera tag (function form) renders through the same catalogs, driven by the activeLANGlocale. →tera_translate_function
The DB-override layer + admin translation editor — file-seeded
catalogs overridden per-tenant in the DB and edited live in the admin —
and Accept-Language middleware are documented in
docs/i18n.md; this chapter covers the
in-process Translator core.