Internationalization Overview¶
Multi-layer i18n strategy spanning backend, admin dashboard, and borrower portal. Currently supports English and Spanish.
Architecture¶
i18n flows through four layers:
Tenant Config (locale, timezone, currency)
↓
TenantLocaleMiddleware (activates per-request)
↓
Backend (gettext, Babel formatters, Jinja2 filters)
↓
Frontend (react-admin Polyglot / browser Intl APIs)
Supported Languages¶
| Code | Language | Status |
|---|---|---|
en |
English | Default, complete |
es |
Spanish | Supported, complete |
Configured in backend/config/settings/base.py:
Per-Tenant Configuration¶
Each tenant has locale, timezone, and currency settings:
| Field | Default | Purpose |
|---|---|---|
locale |
en |
Default language for tenant users |
timezone |
UTC |
IANA timezone for date/time display |
default_currency |
USD |
ISO 4217 currency for monetary values |
These are stored on the Tenant model and activated per-request by TenantLocaleMiddleware.
Locale Flow¶
Request Processing¶
TenantLocaleMiddlewareresolves the language:Accept-Languageheader (if language is inLANGUAGES)- Tenant's
localefield (for dynamic tenants) LANGUAGE_CODEfallback (en-us)
- Activates Django's
translation.activate()andtimezone.activate() - Sets
request.locale,request.tenant_timezone,request.tenant_currency - Sets
Content-Languageresponse header
API Responses¶
API responses return raw values (Decimal, ISO dates). The frontend formats them using browser Intl APIs. Server-side formatting is reserved for PDFs, emails, and compliance documents.
Communication Templates¶
When sending communications:
borrower.language_preferencedetermines the template languageresolve_template_for_language()finds a matching template, falling back to English- Jinja2 filters format currency/dates using the borrower's locale
PDF Generation¶
When generating PDFs:
borrower.language_preferenceselects the template variantrender_pdf()tries{stem}_{lang}{suffix}first (e.g.,monthly_statement_es.html)- Falls back to the English template if no variant exists
Layer Summary¶
| Layer | Technology | Scope |
|---|---|---|
| Backend translation | Django gettext / gettext_lazy |
Model labels, error messages, choices |
| Backend formatting | Babel (common/formatting.py) |
PDFs, emails, compliance docs |
| Template formatting | Jinja2 filters (currency, date, etc.) |
Communication and PDF templates |
| Admin frontend | react-admin Polyglot i18n provider | UI labels, menu items |
| Borrower portal | Browser Intl APIs |
Currency, date formatting |
| Per-borrower preference | borrower.language_preference field |
Template language selection |
See Also¶
- Backend i18n --- Translation markers, message catalogs, Babel formatters
- Frontend i18n --- react-admin and portal i18n
- Localization --- Per-tenant formatting, templates
- Adding a Language --- Step-by-step guide