Skip to content

Localization runtime

Responsibility

The localization runtime selects a language, loads catalogs, translates singular/plural and contextual messages, invalidates translation caches on language changes, provides typed format helpers, and supports translation-valued JSON data.

Entry points

Read src/translations.h, src/translations.cpp, the translation type, plural evaluator, and translation manager. Use _ for runtime strings, contextual/plural helpers where required, and translate_marker only for extraction without runtime translation.

Data ownership

Translation catalogs and manager caches own localized lookup state. Source code and JSON own stable English message IDs/context; UI callers own the formatted result. Cached translated strings must respect the language-generation counter.

Dependencies

Localization depends on gettext catalogs, locale/path discovery, extraction scripts, JSON translation objects, plural rules, fmt type checking, options, fonts, and UI layout.

Lifecycle

Source messages are extracted to POT, translated into PO, compiled to MO, loaded for the chosen language, cached on use, and invalidated when set_language changes the generation.

Invariants

Message/context/plural keys remain stable; placeholders agree across translations; format arguments are type-correct; marker-only strings are translated before display; and a language switch cannot return a previous-language cache entry.

Extension points

Mark new user-facing strings with the appropriate helper and add translator context where the English is ambiguous. Add plural/context APIs centrally, not via manual string concatenation.

Serialization

Save stable IDs or source-language values required by the owning contract, not rendered text. Language choice is user configuration; runtime translation caches are reconstructed.

Tests

Use translation-system and translations tests plus extraction/build checks. Cover context, plural counts, format placeholders, language cache invalidation, JSON translation values, and both localized/non-localized builds.

Performance

Translation occurs throughout rendering. Preserve local caches and generation invalidation, avoid repeated formatting in loops, and never cache across a language change without a token.

CCB divergence

CCB has its own messages, project name, Lua UI strings, Android resources, and translation catalog. Upstream translations cannot replace or overwrite CCB-specific context.

Technical debt

Gettext macros, typed translation, JSON forms, Android resources, and Lua i18n coexist. Keep their extraction and invalidation boundaries documented and tested.