Repository navigation
Conversation
GlotPress highlights only `%1$l` in `%1$ld` and shows the `d` as translatable text, so translators drop it: `ko`, `zh-cn` and `zh-tw` currently have `%1$l`, and `nl` had `%1$l d` in July. That fails `lint_localizations` on every beta. `%1$d` is highlighted whole. See AINFRA-3482. The word count never comes near `Int32.max`, so `%d` formats an `Int` correctly. --- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generated by 🚫 Danger |
The patch table still rewrote translations to `%1$ld`, which the plural fold now rejects against the `%1$d` English, so `ro`'s `one` and `zero` forms would stay rejected even after translators re-translate them. The `ko`, `zh-Hans` and `zh-Hant` entries stay until the new original is on GlotPress, which only happens after the next code freeze. Until then, downloads still return the old `%1$l` values, and removing the entries would fail `lint_localizations`. --- Generated with the help of Claude Code (Opus 5.5), https://code.claude.com
So the next plural doesn't reintroduce the placeholder translators keep breaking in GlotPress. --- Generated with the help of Claude Code (Opus 5.5), https://code.claude.com
There was a problem hiding this comment.
🟢 Approval recommended
The word-count placeholder update has no active review issues.
No open issues 🎉
What changed in this PR
Updates word-count plural placeholders to %1$d so GlotPress recognizes the full placeholder and translators do not accidentally drop its final character. This changes localization preparation; the catalog is not yet read at runtime.
Changes:
- Switches English word-count plurals and their translator comment from
%1$ldto%1$d. - Aligns Korean, Romanian, and Chinese translation patches with the new English placeholder.
- Documents
%1$das the preferred placeholder for counts.
| File | Description |
|---|---|
WordPress/Classes/Plurals.xcstrings |
Updates English word-count placeholders and the translator comment. |
fastlane/lanes/localization.rb |
Retargets word-count translation patches to %1$d. |
docs/localization.md |
Adds count-placeholder guidance explaining the GlotPress limitation. |
Review effort: Balanced
AliSoftware
left a comment
There was a problem hiding this comment.
The change looks good and makes sense to me (but indeed it's be nice to have @jkmassel and @crazytonyli validate with their better comprehension of the new translation process/automation they put in place.
Obviously it'd be even better to have our agents fix GlotPress itself at the source to fix that annoying placeholder highlighting bug they have on %ld. And I think such a fix would be worth it to do upstream anyway. But it might take time for such a fix to be shipped in a new version then deployed on translate.wordpress.org so it's still important to workaround that here too by using %d in the meantime.
| 3. **Use positional placeholders**: `%1$@`, `%2$d` not just `%@`, `%d` | ||
| 4. **No variables in NSLocalizedString**: All parameters must be string literals | ||
| 5. **Use String.localizedStringWithFormat**: Don't use string interpolation | ||
| 6. **Use `%1$d` for counts, not `%1$ld`**: GlotPress highlights only `%1$l` as the placeholder, so translators drop the `d` |
There was a problem hiding this comment.
| 6. **Use `%1$d` for counts, not `%1$ld`**: GlotPress highlights only `%1$l` as the placeholder, so translators drop the `d` | |
| 6. **Use `%1$d` for counts, not `%1$ld`**: GlotPress highlights only `%1$l` as the placeholder, which makes translators often incorrectly drop the `d` |
Description
Switches the English word-count plural in
Plurals.xcstringsfrom%1$ldto%1$d(AINFRA-3482).Caution
@jkmassel @crazytonyli With your work setting the new localization pipeline, you know more about
xcstringsthan I do. I'm not entirely sure changing what I assume was the default Apple format for something different just to please GlotPress is a good approach. But maybe the difference is small enough that we can accept it?GlotPress highlights only
%1$las the placeholder and shows thedas text to translate, so translators drop it:ko,zh-cnandzh-twcurrently have%1$l, which failslint_localizationson every beta and is whyapply_glotpress_translation_patchpatches them by hand.GlotPress highlights
%1$dwhole.The count never comes near
Int32.max, so%dformats anIntcorrectly.Gotchas:
needs_review) for this key, because its validator treats%dand%ldas different. Nothing readsPlurals.xcstringsat runtime yet, so users see no change.%1$ld) without re-checking them against the new English; Re-check kept plural machine cells against English #26263 fixes that.%1$d, so patched values match the new English.ro's entries need this regardless of GlotPress, because Romanian omits the number in those forms and re-translating won't change that. Thekoandzh-*entries stay until the new original is on GlotPress, which needs a code freeze after this lands; removing them is the last step of AINFRA-3482.Testing instructions
PR CI doesn't run the plural lanes for an
.xcstrings-only change, so they ran on a throwaway stacked PR (#26262, closed) — build 35363:generate_strings_file_for_glotpress(as at code freeze) emitted all six word-count originals with%1$d; the same assertion fails on trunk's catalog.download_localized_plurals(as at every beta, withoutANTHROPIC_API_KEY) kept English%1$d, the folded catalog compiles, and it rejected the 48 existing human%1$ldtranslations, falling back to English until GlotPress re-translates.Locally: the catalog compiles with
xcrun xcstringstool compile, the forward flattening emits%1$dfor all six categories, andbundle exec fastlane download_localized_pluralsfolds into a catalog that still compiles.The patch table has no permanent test because it's temporary. Running the real
apply_glotpress_translation_patchon the brokenko,ro,zh-Hansandzh-Hantvalues, then the fold's placeholder check against the catalog English, rejected 6 of 6 sampled cells before the retarget and 0 of 6 after.