Localization¶
quadletman uses Babel and GNU gettext for i18n. The active
locale is resolved from the browser's Accept-Language header at the start of each request.
Supported languages: English (en, default) and Finnish (fi).
Key files¶
| File | Purpose |
|---|---|
quadletman/i18n.py |
Thin gettext wrapper; set_translations(lang) called by middleware; gettext as _ imported by routers |
quadletman/templates_config.py |
Shared Jinja2Templates instance with i18n Jinja2 extension; _() and ngettext() available in every template |
quadletman/locale/quadletman.pot |
Master message catalog — generated by pybabel extract, committed to the repo |
quadletman/locale/{lang}/LC_MESSAGES/quadletman.po |
Per-language translation catalog (human-edited) |
quadletman/locale/{lang}/LC_MESSAGES/quadletman.mo |
Compiled binary — generated by pybabel compile, committed to the repo |
babel.cfg |
Babel extraction config; maps .py and .html files to extractors |
Using translations in code¶
Python (routers and services):
Jinja2 templates — _() and ngettext() are globals, no import needed:
Workflow: adding or changing a translatable string¶
Every user-visible string must be wrapped in _() (singular) or ngettext() (plural). After
adding or changing any such string, run the full catalog update cycle:
# 1. Extract all marked strings into the .pot master catalog
uv run pybabel extract -F babel.cfg -o quadletman/locale/quadletman.pot .
# 2. Merge new/changed strings into each existing .po file
uv run pybabel update -i quadletman/locale/quadletman.pot -d quadletman/locale -D quadletman
# 3. Edit the .po file(s) — translate new or fuzzy entries (see Fuzzy entries below)
# 4. Compile .po → .mo for runtime use
uv run pybabel compile -d quadletman/locale -D quadletman
Commit .pot, all .po files, and the compiled .mo files together in the same commit
as the code change.
Fuzzy entries¶
pybabel update marks auto-guessed translations as #, fuzzy. These are not served at
runtime — the fallback string is used instead. Always review and fix fuzzy entries after
pybabel update. Remove the #, fuzzy comment once the translation is verified.
Adding a new language¶
- Create the directory:
quadletman/locale/{lang}/LC_MESSAGES/ - Initialize the catalog:
- Add the language code to
AVAILABLE_LANGSinquadletman/i18n.py. - Translate all
msgstrentries in the new.pofile. - Compile:
uv run pybabel compile -d quadletman/locale -D quadletman
Finnish vocabulary¶
Use these canonical Finnish terms. Do not invent alternatives.
| English | Finnish | Notes |
|---|---|---|
| Container | Kontti | Plural: kontit; partitive: kontteja; inessive: konteissa. Not "säiliö" or "containerit". |
| Image | Levykuva | Plural: levykuvat. Not "säilökuva". |
| Volume | Levyosio | |
| Image store / image registry (local) | Levykuvataltio | Not "kuvavarasto". |
| Podman store / Podman storage | podman-taltio | Lowercase. Not "Podman-varasto". |
| Podman network | podman-verkko | Inflects: podman-verkollaan etc. Not "Podman-network". |
| Non-host containers | host-verkkoon kytkeytymättömät kontit | Not "ei-host-kontit". |
| Secret | Salaisuus | |
| Compartment | Osasto | |
| Cancel | Peruuta | |
| Save | Tallenna | |
| Delete | Poista | |
| Create | Luo | |
| Update | Päivitä | |
| Add secret | Lisää salaisuus | |
| New value | Uusi arvo | |
| New secret value… | Uusi salaisuuden arvo… | Placeholder text. |
| Secret value… | Salaisuuden arvo… | Placeholder for new secret. |
| Name | Nimi | |
| Value | Arvo | |
| Hook | Koukku | Notification hooks. |
| Build (noun) | Koonti | Plural: koonnit. The .build Quadlet concept. Not "rakennus". |
| Build unit | Koontiyksikkö | The .build Quadlet unit file. |
| Build (verb) | Koota | "built from" → "koottu". Not "rakentaa". |
| Built (past participle) | Koottu | "Locally Built Images" → "Paikallisesti kootut levykuvat". |
| Rebuild | Koota uudelleen | Not "rakentaa uudelleen". |
| Build-time | Koontiajan / Koonnin aikainen | Context-dependent. |
| Any container | Mikä tahansa kontti |
Note: some older strings used "säiliö" for Container and "rakennus" for Build. The canonical terms are Kontti and Koonti respectively. Correct any occurrence of "säiliö" or "rakennus" (for Build) found during translation work.
Checklist when adding a user-visible string¶
- Wrap the string in
_()orngettext()at the call site (Python or Jinja2). - Run the full extract → update → translate → compile cycle.
- For Finnish: verify the term against the vocabulary table above.
- Stage
.pot,.po, and.mofiles in the same commit.