🌐 i18n(i18n): add multilingual support with translations

- create i18n.py for managing translations and resolving locale
- add German and English translations for various UI components
- integrate translation functions into templates for dynamic language support
This commit is contained in:
nocci 2025-12-06 13:58:46 +00:00
parent 1aafd6d5a3
commit cc7c75ba33
11 changed files with 548 additions and 157 deletions

View file

@ -18,6 +18,9 @@ from .utils import (
ensure_csrf_token,
validate_csrf,
)
from jinja2 import pass_context
from .i18n import AVAILABLE_LANGUAGES, resolve_locale, translate
from .auth import (
hash_password,
verify_password,
@ -30,6 +33,7 @@ app = FastAPI(title="FleetLedger")
app.mount("/static", StaticFiles(directory="app/static"), name="static")
templates = Jinja2Templates(directory="app/templates")
templates.env.globals["languages"] = AVAILABLE_LANGUAGES
# Session middleware (server-side session based on signed cookie)
SESSION_SECRET = os.getenv("SESSION_SECRET")
@ -50,6 +54,23 @@ app.add_middleware(
)
@app.middleware("http")
async def add_locale_to_request(request: Request, call_next):
request.state.locale = resolve_locale(request)
response = await call_next(request)
return response
@pass_context
def _t(ctx, key: str, **kwargs) -> str:
request = ctx.get("request")
locale = getattr(request.state, "locale", "de") if request else "de"
return translate(key, locale, **kwargs)
templates.env.globals["t"] = _t
@app.on_event("startup")
def on_startup() -> None:
"""Initialize database on startup."""
@ -74,6 +95,17 @@ def service_worker() -> FileResponse:
)
@app.get("/lang/{code}", include_in_schema=False)
def switch_language(code: str, request: Request):
"""Persist preferred language in session and redirect back."""
code = code.lower()
if code not in AVAILABLE_LANGUAGES:
return RedirectResponse("/", status_code=303)
request.session["lang"] = code
referer = request.headers.get("referer") or "/"
return RedirectResponse(referer, status_code=303)
# ------------- Auth: Register / Login / Logout -------------