Next-Level Code. Nexuvibe Style ...

Hrs
Min
Sec
Plural forms • gettext 2026

ICU-Style Messages and Plural Forms:
What Automated Assists Often Get Wrong—and How to Catch It

Developers who ship Java or Android stacks think in ICU MessageFormat strings with nested selects and plural branches. WordPress WooCommerce stacks still live mostly in gettext: singular msgids, plural msgid_plural pairs, and PO headers that declare a Plural-Forms formula per locale. When teams run bulk assists across thousands of rows, plural blocks are where fluent-looking prose quietly becomes grammatically illegal for Polish cart totals, Russian stock counts, or Arabic order summaries. This guide connects ICU intuition to gettext reality and gives reviewers concrete traps to hunt before MO files hit production.

12 min read
Updated 2026
WooCommerce i18n
ICU style messages versus gettext plural forms WordPress Loco WooCommerce ngettext automated translation QA 2026

Plural handling is not a cosmetic grammar exercise. It changes which word receives the number, which case ending attaches to the noun, and whether zero is grouped with one or with many. gettext encodes that complexity as a formula in the PO header plus one msgstr per plural index for each entry. An assist that writes only one msgstr for a six-form Slavic locale has already failed, even if the English singular and plural pair looked straightforward.

ICU MessageFormat expresses similar decisions with explicit `{plural …}` branches inside one string. gettext spreads them across indexed slots. Reviewers who understand both models catch mistakes faster: they know when a vendor copied ICU patterns into English source without giving translators structural room, and they know when assists collapse branches because the PO editor view hid the plural grid.

Paired with Loco workflows, Loco AI Auto Translator gettext assists with plural-form-aware prompts for WooCommerce ngettext and _n() strings can insist on complete msgstr index coverage before reviewers accept a batch.

What this guide covers
How ICU plural branches differ from gettext indexed msgstr slots.
Reading Plural-Forms headers and knowing when they disagree with CLDR.
WooCommerce hotspots: stock, cart counts, reviews, subscriptions.
Failure modes from bulk assists on plural entries.
QA matrix: counts to test per locale family.
Prompt and glossary habits that protect plural integrity.

ICU MessageFormat versus gettext mental models

ICU strings often bundle plural, gender, and ordinals inside one template. gettext traditionally splits concerns: `_n()` supplies singular and plural English roots, translators fill indexed variants, and separate APIs handle contexts. When product managers ask why Russian needs more than two boxes, the answer is linguistic, not bureaucratic. Assists trained on English-French pairs may hallucinate a binary plural world unless prompts state the target locale’s cardinality explicitly.

WooCommerce extensions sometimes import phrasing from platforms that used ICU internally. English msgids may include curly placeholders reminiscent of MessageFormat while still compiling through PHP sprintf. Reviewers should flag those hybrids early: they increase the chance that an assist copies brace syntax into msgstr where WordPress expects percent placeholders or plain words.

One concept, two encodings

Treat ICU as documentation of intent and gettext as execution on WordPress. Your job is to ensure every branch ICU would select has a corresponding msgstr index after MO compilation.

Never merge branches in translation

If an assist proposes one Russian sentence that tries to cover both paucal and many forms with a slash, reject it. Natural language does not compress cardinality that way on customer-facing totals.

The ICU user guide on message formatting helps bilingual engineers explain brace syntax to translators who only see PO files. Shared vocabulary shortens triage meetings.

Plural-Forms headers and CLDR alignment

Every PO file carries a Plural-Forms expression defining how n maps to plural indices. If that formula disagrees with what WooCommerce runtime expects for the locale, translators can fill every slot perfectly and still see wrong branches at runtime. Verify headers when merging catalogs from multiple contributors; a stale formula copied from an old theme bleeds across plugins.

Locale family Cardinality reminder Review focus
Slavic (ru, pl, uk) Three or more forms 21, 22, 5, 0 test counts
Arabic Six-way rules in many catalogs Zero and two through ten
East Asian (ja, ko, zh) Often one form Still test counters with classifiers if mixed-language SKUs appear
Romance (fr, es) Two forms typical Zero handling differs by project style

The CLDR plural rules chart is the quickest sanity check when someone questions whether your PO header matches industry expectations for a locale.

Zero, fractions, and ICU selects that WordPress still splits across strings

ICU can nest `{select, gender}` beside `{plural}` in one template. WordPress PHP still tends to expose separate gettext calls for gendered variants, with `_x()` or context markers, rather than one mega-string. That architectural split is healthy for translators who never see MessageFormat braces, but it means your English source must stay parallel: if an assist rewrites one branch with a different placeholder count, sibling entries desynchronize and runtime sprintf warnings return.

Zero is not universal. Some locales treat zero like plural, others like a dedicated form, and marketing copy sometimes overrides CLDR for tone. Document house rules in your glossary so assists do not improvise between “no items” and “zero items” per batch. Fractional quantities in weight-based shipping or metered billing add another layer: English may pluralize “0.5 kilograms” while another language keeps a singular measure noun. If WooCommerce passes floats into `_n()`, confirm the PHP side rounds or formats before translation so translators are not asked to defend impossible grammar against raw binary floats.

Ordinal labels (“1st”, “2nd”) are not the same problem as cardinal plurals, yet teams bundle them in the same Jira epic. If a block editor pattern hardcodes English ordinals beside localized month names, assists may translate the month while leaving ordinals Latin. Split those strings or supply ICU-free gettext entries per ordinal slot if your stack demands it, then audit with native speakers who care about school-grade typography.

When product owners ask for parity with an Android app that already ships ICU templates, resist blindly pasting brace syntax into WordPress msgids. Instead, translate the intent into `_n()` pairs plus companion `_x()` entries, and keep a mapping document for engineers who maintain both codebases. That document becomes the contract reviewers use when they diff assists across repositories.

WordPress APIs: _n(), _nx(), and comments for translators

Core and WooCommerce wrap plural-sensitive strings with `_n()` and variants. Translator comments should state what the number represents: items in cart versus pages of results. Assists without that comment may choose agreeable wording that mismatches gender or animacy in the target language. Demand comments in vendor code the same way you demand docblocks for risky filters.

The WordPress developer guide to pluralization shows how `_n()` pairs msgid and msgid_plural. Share it with junior reviewers before they approve their first Russian electronics catalog.

`_nx()` adds context for duplicate English words with different plural behavior, such as “comment” in admin lists versus storefront reviews. Assists often miss context markers and merge those rows, creating a single msgstr that cannot satisfy both screens. Before approving any batch, sort Loco by context column and verify that parallel entries kept distinct msgids stayed distinct in translation.

Translator comments that mention units (“weight in grams”) or currency ISO codes prevent assists from inventing incompatible measure words per plural branch. Treat missing comments as a release blocker for commerce domains the same way you would treat missing nonce checks on checkout AJAX: the storefront might still render, but you are shipping latent defects.

WooCommerce surfaces where plurals matter most

Stock and inventory notices flip between singular and plural multiple times per session. Subscription renewals mention counts of shipments, seats, or licenses. Bundle extensions describe included child products. Each string is a plural trap if English reused the same pattern for unlike quantities. Build a spreadsheet of the top twenty plural msgids in your vertical and test them with boundary counts: 0, 1, 2, 5, 11, 21, 102.

Reviews and ratings introduce “one review” versus “N reviews” copy. Social proof widgets may concatenate strings from two domains; verify both agree on plural policy or shoppers see inconsistent grammar between the product tab and the summary chip.

Staging recipe
Create SKUs with quantities that land on each plural index. Script adds to cart in staging so you can photograph each state without manual guesswork.

Coupon and fee lines reuse plural machinery for “You saved X” ribbons. Loyalty extensions that award points per currency unit can emit unexpected counts during partial refunds. Extend your spreadsheet beyond core cart strings to third-party fee labels so assists never ship a half-localized checkout summary. Include transactional emails and SMS templates that echo cart counts, because those channels often compile from different MO domains than the web theme.

Nexu WP Loco AI Auto Translator with prompts requiring complete plural msgstr grids before WooCommerce MO compile reduces the classic failure mode where only the first slot is filled and later indices fall back to English.

How bulk assists break plurals even when singular rows look perfect

Assists optimize for the visible paragraph. Plural entries look like duplicates in a narrow editor column, so bulk pipelines sometimes collapse variants or copy the singular into every index to “save space”. Human reviewers in a hurry may accept that if they only read English side by side. Runtime then picks index 2 for a count of five and prints broken grammar next to the cart total.

Another failure mode is placeholder drift: `%d` count moves relative to surrounding words in Slavic clauses. Each plural branch may need a different word order. Assists that preserve English order across every index defeat the purpose of distinct forms.

Glossaries help with lexical consistency: if the singular product noun is locked, plural stems in each index stay aligned instead of drifting synonyms per branch.

Bulk jobs: segment plural-heavy domains and watch progress

Run commerce-critical plural domains in smaller batches so reviewers can spot-check indices between chunks. Mixing hundreds of unrelated admin strings into the same job as cart plurals buries risk. Tag jobs in your ticket system with locale cardinality so Polish batches never inherit French-default assumptions.

Bulk Loco AI translation progress monitoring plural gettext entries for WooCommerce catalogs

Caption: Pause milestones to audit plural grids, not only singular paragraphs.

WordPress Loco AI plugin batch fills with plural-safe review checkpoints for high-cardinality locales pairs well with scripted smoke tests that hit each plural index automatically after MO deploy.

Per-string rescue and gettext tooling habits

When only one plural entry is wrong, fix that index in Loco, recompile, and add the count to your golden test set. Escalate upstream if English msgid_plural itself is misleading, such as using “items” for a count that can be non-integer in subscriptions.

The GNU gettext manual on translating plural forms remains the authoritative description of msgid_plural and indexed msgstr lines; link it in onboarding for every reviewer who joins mid-project.

MO compile hygiene, fuzzy flags, and regression harnesses

A PO file can look complete in Loco while msgfmt rejects it because one plural line lost its index prefix or picked up a stray quote from a bad paste. Wire `msgfmt –check` into CI for each locale you ship, not only for English. The failure logs should name the file, line, and msgid so assists do not force humans to binary-search forty languages.

Fuzzy markers are a signal, not decoration. When English msgid_plural changes, gettext tools mark translations fuzzy; assists that strip fuzzy without revalidating every index recreate the exact bug you thought you avoided with fresh English. Policy: no merging fuzzy rows in plural entries until a native reviewer re-runs the golden counts for that locale.

Build a regression harness that loads WooCommerce cart fixtures with scripted quantities. Capture screenshots or HTML snippets per locale and store hashes. After each assist batch, rerun the harness and diff: any unexpected English fragment in a plural slot fails the build. This is cheaper than explaining to executives why Polish Black Friday revenue dipped after a “small wording update.”

For Arabic and Hebrew storefronts, pair plural review with direction checks: numerals may sit in a neutral European digit block while words stay RTL. Assists that only mirror English digit placement can produce legal grammar with illegal reading order. Extend your harness with forced RTL browser profiles so plural and direction regressions surface in one pipeline stage.

Finally, version your Loco export bundles alongside MO binaries in release artifacts. When a customer reports a plural bug six weeks later, you can diff the exact PO revision that reached production instead of guessing whether a nightly assist overwrote reviewer edits.

Providers, settings parity, and turbo throughput

Switching translation endpoints can change how aggressively assists collapse redundant-sounding branches. After any provider swap, rerun plural golden counts. Export prompt JSON with your MO artifacts so staging matches production behavior.

Loco AI Auto Translator WordPress settings for default gettext policies on plural strings

Caption: Baseline settings before enabling faster batch modes on plural-heavy WooCommerce domains.
Turbo mode Loco AI Auto Translator with plural QA gates for large WooCommerce gettext jobs

Caption: Higher throughput without plural review gates is how bilingual stores lose trust in a single afternoon.

Document ownership: plural QA is not “whoever is online”. Assign a native reviewer per high-cardinality locale and a backup before holiday freezes.

Escaping matters: a stray `%` in Russian copy can break sprintf and fall back to English at runtime. Instruct assists to preserve percent sequences exactly and to avoid typographic percent signs unless the source used them. The same rule applies to numbered placeholders when extensions mix positional and named tokens—one swapped index in a six-form grid is enough to scramble a subscription renewal banner.

Block themes and interactive cart fragments may hydrate strings from JavaScript packs that do not share WooCommerce PHP catalogs. If your storefront shows one plural rule in PHP and another in a client bundle, shoppers experience whiplash during AJAX updates. Keep a cross-surface string inventory and refuse assists that only touch one half of the pair.

Finally, teach finance and legal stakeholders why “fixing a typo” in English msgid_plural is never a one-line change: every dependent msgstr index must be revalidated, MO files rebuilt, and caches purged. When they understand the blast radius, they stop sneaking last-minute copy edits into freeze week without a plural checklist.

ICU familiarity helps teams speak precisely about intent; gettext discipline ensures WordPress actually renders that intent. Where the two diverge, fix English source or PO structure before blaming translators for being pedantic.

If you need Loco-connected assists that treat plural grids as first-class citizens, the Loco AI Auto Translator WordPress extension for WooCommerce gettext plural forms and ngettext safety at scale keeps high-cardinality locales from collapsing into English fallbacks under deadline pressure.

Loco AI Auto Translator thumbnail prompts for WooCommerce plural gettext

Loco AI Auto Translator
Ship plural-aware gettext fills with the same rigor ICU-native teams expect from MessageFormat.

Get Loco AI Auto Translator

Picture of Mahdi Jabinpour

Mahdi Jabinpour

As a sales-driven developer and the founder of NexuWP, Mahdi focuses on building WordPress solutions that don't just work—they convert. From AI-powered bulk translation engines to high-efficiency media offloading, he helps business owners automate the "grind" so they can focus on global growth. He is a pioneer in integrating advanced LLMs into the WordPress workflow.

RELATED POSTS

RELATED POSTS

3 Reviews
Robert Miller 5 months ago

Finally, a guide that speaks both dev and PM. Cut our i18n debates in half lifesaver!

mehdiadmin 5 months ago

We're

Daniel Anderson 5 months ago

Hey, just read this and wow finally an explanation for why my Woo cart counts mess up in

Mahdi Jabinpour 5 months ago

I'm happy the cart count details finally make sense those can be frustrating until everything falls into place

Richard Jones 5 months ago

This guide saved me hours debugging Polish cart totals. ICU's nested branches make sense, but gettext's indexed slots still trip me up. wish it had more WooCommerce specific examples though.

Please log in to leave a review.