Repository navigation
feat(i18n): translatable UI in 12 languages with browser language detection - #9
Merged
Merged
Conversation
- Flask-Babel with English as the source language
- language per request: chosen language (sv_lang cookie), else the
best Accept-Language match (regional tags fall back to the base
language), else English; 12 supported locales
- POST /language stores the choice ("Automatic" clears it), with a
safe same-site redirect back
- reusable language switcher; <html lang> follows the locale
- JS strings: N_() marks them for extraction, components/js_i18n.html
exposes window.svT() backed by the current catalog
- login page converted as the reference pattern
- babel.cfg for pybabel extraction
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The German documents stay legally binding. German UI shows them; every other UI language shows the English translation (content/*.en.md and tube_rules.RULES_EN). A translation is only used when it carries the same termsVersion/privacyVersion as the original, so the version users accept never depends on their language. Discord output and version checks keep using the German original. The consent phrase is shown per language (AKZEPTIERE / ACCEPT); either is accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All user-visible text now goes through gettext with English msgids: 36 templates (text, attributes, inline script strings via |tojson), 344 Python messages (gettext at request time, lazy_gettext for module constants), and 52 static JS strings (svT() + JS_MESSAGES). The German catalog restores the previous UI wording: 1083/1083 messages. - WEBUI/translations: messages.pot plus compiled de catalog (.mo is committed so installs need no build step) - scripts/check_translations.py: placeholders must match the source and literal % must be %% (Flask-Babel formats every message) - mobile VOD page counter is found via data-vod-page-counter instead of matching the German word "Seite" - values compared as keys or stored in the database (stream-title sentinel, clip_engine status checks, seeded group descriptions, storage last_error texts asserted by tests) intentionally stay German - tests: the storage page test now requests Accept-Language: de, so its German assertions (incl. assertNotIn) keep their meaning; no assertion was changed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
French, Spanish, Italian, Brazilian Portuguese, Dutch, Polish, Turkish, Japanese, Simplified Chinese and Korean, 1083/1083 messages each, validated for matching placeholders, escaped percent signs, HTML tags and the locale's plural form count. These translations have not been reviewed by native speakers yet; the README says so and CONTRIBUTING explains how to correct them. CI runs scripts/check_translations.py and fails when the committed .mo files do not match their .po sources. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The admin task queue used four fixed columns (about 60px each on a phone). Spanish, Italian, Portuguese and Polish labels pushed the counts out of their chips. The grid now fits as many 96px+ columns as there is room for: one row on desktop, two on phones. Found by a layout scan of 10 pages x 2 widths in all 12 languages (240 renders); after this fix it reports no clipped content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The web UI is now translatable and follows the browser language.
sv_langcookie, then the bestAccept-Languagematch (a region falls back to its base language, e.g.de-AT→de), then English.POST /languageonly redirects to a safenextURL.AKZEPTIEREandACCEPT.window.SV_I18N,svT())..mofiles are committed.scripts/check_translations.pychecks placeholders,%%escapes and HTML tags in every locale, and CI verifies that the compiled catalogs are up to date..task-queue-statsnow wraps for long translations on phones.Operator notes
Flask-Babel>=4.0.0,<5.Known limitations
last_errortexts and the default group descriptions.Test plan
python -m unittest discover -s tests: 174 tests, OK (skipped=1)ruff check .python scripts/check_translations.py: 0 issues<html lang>🤖 Generated with Claude Code