-
Notifications
You must be signed in to change notification settings - Fork 16.6k
Description
I'm working on the Portuguese (and pt-BR) UI translations. While using breeze ui check-translation-completeness I ran into behaviour that felt inconsistent and made it hard to know what to translate or remove.
The checker wasn’t clear on which keys are actually required per locale: sometimes it asked for plural forms that don’t exist in English (e.g. only _one there), and sometimes it reported keys as "extra" when they were just plural variants that the app never uses because it never passes count for that key. So we had "extra" (typos, legacy) and "unused" (those plural forms) as two different things, but for the translator both mean "not required." Coverage was also misleading because it counted keys that still had TODO: translate, so it didn’t reflect how much was really translated. And the flag --remove-extra didn’t make it obvious that the goal is to remove anything that isn’t required (unused at runtime); I’d find --remove-unused clearer.
To understand when a key is really used, I looked at how English, Arabic and Portuguese use the same keys.
English is the source. It often has only _one and _other. When the UI passes a count, the message has {{count}} in the value (e.g. deleteConnection_other: "Delete {{count}} connections"). Some keys have only _one and no count, e.g. dagWarnings.error_one: "1 Error"; the code never calls that with count, so no error_other is ever used. For file upload, EN has only files_other: "{{count}} files"; a locale can add files_one for "1 file" but EN doesn’t define it.
admin.json (EN):
"delete": {
"deleteConnection_one": "Delete 1 connection",
"deleteConnection_other": "Delete {{count}} connections",
...
}components.json (EN):
"dagWarnings": { "error_one": "1 Error", ... },
"fileUpload": { "files_other": "{{count}} files" }So for deleteConnection the app does use count, so each locale needs all its plural forms for that base. For dagWarnings.error it never uses count, so only error_one is needed; any error_other or error_zero in a locale is never used. For fileUpload.files the app uses count; something like files_one in PT is optional.
Arabic has zero, one, two, few, many, other. For bases where EN has {{count}}, AR needs all of those (e.g. deleteConnection_zero/one/two/few/many/other). For dagWarnings.error, EN has only error_one, so at runtime only that is used; if AR has error_zero, error_other, etc., they’re never used and the checker should list them in one "unused" bucket, not as a separate "extra" category.
Portuguese usually needs only _one and _other. Same idea: if EN has no {{count}} for a base, only the EN keys are required; anything else in the locale (e.g. error_other, error_zero) is unused. If EN has {{count}}, PT only needs the plural forms that PT’s rules use; adding files_one for "1 arquivo" is fine but not required by EN.
I’m proposing the checker behave like this:
- Required: EN keys plus, for each plural base where EN has
{{count}}, all plural forms that the locale’s language needs. So required = EN keys ∪ locale plural expansion only for those bases. - Missing: required keys that the locale doesn’t have.
- Unused: any key in the locale that isn’t required (typos, legacy, or plural forms for bases that don’t use
{{count}}in EN). One list, no separate "extra." - Coverage: translated / total required, where translated = keys with a real value (not
TODO: translate). - Table: Required (base EN), Required (plural), Total required, Translated, Missing, Coverage, TODOs, Unused.
- Flag: rename
--remove-extrato--remove-unusedand update docs/help.
Acceptance criteria
- Required = EN keys + locale plural expansion only for bases with
{{count}}in EN. - Single Unused list; unused = locale keys − required.
- Coverage = translated / total required, excluding TODO.
- Table columns: Required (base EN), Required (plural), Total required, Translated, Missing, Coverage, TODOs, Unused.
- Flag
--remove-unusedand docs/help updated. - Tests updated/added as needed.