Skip to content

feat(i18n): add Polish locale (#216) - #219

Closed
shockalotti wants to merge 1 commit into
mainfrom
feat/locale-pl
Closed

shockalotti wants to merge 1 commit into
mainfrom
feat/locale-pl

Conversation

@shockalotti

Copy link
Copy Markdown
Contributor

Closes #216.

Adds internal/i18n/locales/pl.json, so Polish joins every booker-facing surface: booking page, manage page, embed widget, the four emails and the calendar invite.

Nothing else was needed in code, which is the design: init() globs the locale directory, and the switcher takes its display name from x/text CLDR data, so the picker shows "Polski" on its own.

Provenance

The strings are kybeq's proposal from #216. Credit to him: this is the first non-English locale in the repo that did not start as an LLM draft, which matters given the README's standing caveat about machine translations.

Validation

  • 169/169 keys, exactly matching en.json, no missing and no extras.
  • Same-keys and printf-verb guards pass unchanged.
  • TestDateTablesMatchCLDR initially failed on 19 date abbreviations, which I corrected:
key group proposed CLDR (Polish)
month_short_* (12) Sty, Lut, Gru, ... sty, lut, gru, ... (lowercase)
dow_short_* (7) Pon, Wt, Śr, ... pon., wt., śr., ... (lowercase + trailing dot)

date_format (%[1]s %[2]d %[3]s %[4]d) and clock_format (24h) already match Polish convention, so those are used as given.

go test ./... green.

Docs updated for the count: README, ARCHITECTURE §23, and CLAUDE.md.

Note

The other / others keys still only express singular vs plural, which cannot cover Polish paucal forms fully. That is a pre-existing limitation of the key design, not specific to this locale, so I left kybeq's wording alone rather than inventing a scheme here.

🤖 Generated with Claude Code

Add internal/i18n/locales/pl.json, so Polish joins the booker-facing
surfaces: booking page, manage page, embed widget, the four emails and the
calendar invite. Nothing else is needed - init() globs the locale directory,
and the switcher reads its display name from x/text's CLDR data, so the
existing picker shows "Polski" automatically.

The strings come from kybeq's proposal in #216. The JSON is complete against
en.json (169/169 keys, no extras) and passes the same-keys and printf-verb
guards unchanged.

The 19 date abbreviations had to be corrected to match CLDR, which the
TestDateTablesMatchCLDR guard checks against Intl:

  - month_short_* are lowercase in Polish CLDR (Sty -> sty, Gru -> gru, ...)
  - dow_short_* are lowercase with a trailing dot (Pon -> pon., Śr -> śr., ...)

date_format ('%[1]s %[2]d %[3]s %[4]d') and clock_format ('24h') already match
Polish convention, so the proposal is used as given there.

Docs updated for the new count: README, ARCHITECTURE \u00a723 and CLAUDE.md.

Credit: strings by kybeq (#216).

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — two translation slips inline, plus a docs reconciliation worth a look.

Reviewed changes

  • New Polish locale — adds internal/i18n/locales/pl.json (169 keys, parity with en.json) covering the booking page, manage page, embed widget, the four emails, the assistant and the calendar invite.
  • Docs count — bumps the shipped-locale count from 9 to 10 in README.md, docs/ARCHITECTURE.md §23 and CLAUDE.md.

ℹ️ Locale docs still contradict the change

The locale file itself is mechanically sound — key parity, printf-verb parity and CLDR date checks all pass — but the docs this PR edits still disagree with both the PR's premise and the tree. §23 still says Polish needs a plural-rule selector before it can ship correctly, still calls every non-English locale an LLM draft, and the counts/lists omit the already-shipping Greek locale. Worth reconciling in this PR so the documented state matches the code.

Technical details
# Locale documentation reconciliation

## Affected sites
- `CONTRIBUTING.md:77` — still says "ships 9 locales (`en es fr fr-CA de it pt nl sv`)" and omits `pl`; README/ARCHITECTURE/CLAUDE were updated but this one was not.
- `docs/ARCHITECTURE.md:1232` — says 10 locales and omits `el`; the tree has 11 `internal/i18n/locales/*.json` files, and `el.json` is a complete Greek locale that `init()` embeds and the matcher serves like any other. Same omission in `README.md:203-206` and `CLAUDE.md:143`.
- `docs/ARCHITECTURE.md:1332` — "Every non-English locale is an LLM draft with no native review" is no longer true for `pl` per the PR provenance.
- `docs/ARCHITECTURE.md:1342-1344` — the known-limitations section explicitly names Polish as needing a real plural-rule selector "before they can ship correctly". This PR ships it; the only affected key in practice is `other`/`others` (see the inline note), so either relax the limitation or defer the locale.

## Required outcome
- Any locale count/list in README, ARCHITECTURE §23, CLAUDE.md and CONTRIBUTING reflects the locales that actually ship, including `el` if it is meant to ship.
- §23's translation-quality and plural-limitation claims agree with shipping Polish.

## Open questions for the human
- Is `el.json` intended to ship? If so it should be listed; if not, this PR's count should not be read as authoritative.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash | 𝕏

"email_calendar_outlook": "Outlook",
"email_booking_reference": "Numer rezerwacji: %s",
"email_manage_link_intro": "Aby zmienić termin lub anulować rezerwację, przejdź do:",
"email_manage_link_intro_reschedule": "Aby ponowanie zmienić termin lub anulować rezerwację, przejdź do:",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ponowanie is not a Polish word — both this string and email_rebook_intro (line 138) need ponownie (“again”). As written, the reschedule and rebook emails show “Aby ponowanie zmienić termin…” / “Aby zarezerwować ponowanie…”.

"assistant_error": "Przepraszamy — coś poszło nie tak. Użyj poniższego kalendarza.",
"assistant_disclosure": "Rozmawiasz z automatycznym asystentem, a nie z człowiekiem.",
"other": "inny",
"others": "inni",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

others is always rendered after a numeral ({{n-3}} others), and Polish numerals 2+ take the genitive here — 2 innych, 5 innych, not 2 inni. inny on line 39 is fine for the singular case; innych keeps the 2-form limitation from producing ungrammatical text for every count above one.

@kybeq

kybeq commented Nov 4, 2026

Copy link
Copy Markdown

Thank you! GOAT!

@shockalotti

Copy link
Copy Markdown
Contributor Author

Closing as superseded by #220, which merged as 0817f8f.

This was an earlier attempt at the same file and had the right CLDR dates, but it went in before the review found two things:

  • email_rebook_intro / email_manage_link_intro_reschedule still said "ponowanie" (should be "ponownie").
  • others was "inni"; it is "innych" — genitive plural after a numeral, confirmed by kybeq on Polish translation #216.

#220 carries those fixes plus the doc updates, so nothing here is lost. The README language-count edit from this branch is picked up in #222 instead, since it was also stale for Greek.

@shockalotti shockalotti closed this Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Polish translation

2 participants