v1.17.0 — Localized dashboard, eight complete locales
Minor release. calrs now speaks your language on both sides of the booking link. No migrations, no configuration change, and no visible difference for English users.
The host side is localized
The dashboard, settings, every form, the availability troubleshooter, date overrides, invite management, the admin panel and the sign-in pages all render through Fluent. Until now you could offer guests a booking page in their own language but had to administer it in English — which is what @typovrak pointed out in #195.
The language resolves once in the auth extractors, where the user row and the request headers are both already in hand: saved preference first, then Accept-Language. So the language dropdown that shipped in 0.x as "foundation for the dashboard translation pass" finally does something.
Validation errors and the bare responses the booking flow returns without page chrome are localized too — including a batch on the guest side that had never been covered, despite the guest flow being described as done.
All eight locales are complete
German, Spanish, Italian, Polish and Brazilian Portuguese each gained 821 keys; Estonian all 987 from an empty file. Every locale now carries 1003 keys, and a test keeps it that way.
Each locale follows the register its earliest translations chose — du, tu, tú, ty, você, sa — rather than a formal one, and matches the English voice on the details that usually drift between translators: the same ellipsis character per string, the same softening on validation errors, and one rendering per English sentence where the same sentence appears under two keys.
Polish carries the three plural categories its grammar needs rather than English's two, so 2 członkowie and 5 członków are both right.
Native review is very welcome on Hosted Weblate — Estonian most of all, since it had no prior translations to take terminology or register from.
Security fix
The "booking can no longer be cancelled" page put the host's own email address into a mailto: href and into the link text through a filter that turns off escaping, so an address containing quotes and angle brackets reached the guest's browser as markup. Present in 1.16.0 and earlier.
It was found by a structural test added while localizing: in any translated sentence carrying markup, every value spliced in must be escaped. That rule now fails the build rather than depending on someone noticing in review.
Upgrading
Drop-in. No schema changes and no new configuration. Existing instances keep whatever language their users had set; English users see no difference.
910 tests. Full detail in CHANGELOG.md.