Files
mc-webui/app
MarekWoandClaude Opus 5 05f502ee53 feat(i18n): translate the System Log panel (stage 1)
First vertical slice: /logs chrome in English and Polish. Small on purpose —
~13 strings — but it exercises every part of the mechanism end to end: the head
include, the catalog route, the cookie, server-rendered t()/tn(), client-side
t()/tHtml()/tn(), a JS-rendered plural, and a rebuilt <select>.

Translated: title, pause/clear tooltips, the two "All ..." filter options, the
search placeholder, the reset tooltip, the loading and load-failed messages, and
the entry counter.

Deliberately NOT translated, per the boundary in docs/translations.md: the log
lines themselves and the DEBUG/INFO/WARNING/ERROR level names. Those are
protocol-side identifiers — the level filter also compares against them, so
translating the labels would be a step toward breaking the filter. Marked with a
comment in the template so the next person does not "fix" it.

The counter is the interesting case: English has two plural forms and Polish
four, so "100 entries" is "100 wpisów" while "2 entries" is "2 wpisy". Rendered
by tn() through Intl.PluralRules on the client and the matching rule table on
the server, which agree.

Also fixed in scripts/i18n_check.py: it warned when a markup-free value was used
via tHtml(), which is wrong and actively harmful advice. What tHtml() buys at an
innerHTML sink is param escaping, not markup support — the warning would have
pushed people toward t() in exactly the place where t() is the XSS hazard. The
error in the other direction (markup used via t()) stays. Output streams are now
forced to UTF-8 so `--missing pl > todo.txt` produces a usable file on Windows
rather than mojibake.

Verified in the browser: every chrome string differs between en and pl, level
names unchanged, no catalog key leaked into the page, the count stays translated
after filtering, and the filter bar wraps without overflow at 360px in Polish.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 17:49:09 +02:00
..