Rustango docs
← Cookbook

Chapter 18 — Internationalization (i18n)

6 tests, no DBrustango::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-CAfr → 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 — gettext lookup + missing-key / unknown-locale / regional (fr-CAfr) fallback. → gettext_lookup_and_fallback
  • §18.141 — {name} placeholder substitution via translate. → placeholder_substitution
  • §18.142 — ngettext (singular/plural) + CLDR plural_category + per-category translate_plural (Polish one/few/many). → pluralization
  • §18.143 — Accept-Language negotiation 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 active LANG locale. → 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.