وب مدرن، رابط کاربری و تجربهی وب · فصل ۷ — Locale، Translation Memory و QA · 56
ICU MessageFormat and Locale-Aware Formatting
Design one bounded locale-aware message contract, format variables with locale-aware primitives, preserve translator-reorderable message units, and prove behavior across contrasting locale fixtures. میتواند «ICU MessageFormat و Locale-aware Formatting» را در یک feature محدود طراحی/پیادهسازی کند و correctness، accessibility یا failure behavior مرتبط را اثبات کند.
Lesson summary
Design one bounded locale-aware message contract, format variables with locale-aware primitives, preserve translator-reorderable message units, and prove behavior across contrasting locale fixtures.
میتواند «ICU MessageFormat و Locale-aware Formatting» را در یک feature محدود طراحی/پیادهسازی کند و correctness، accessibility یا failure behavior مرتبط را اثبات کند.
This lesson produces
میتواند «ICU MessageFormat و Locale-aware Formatting» را در یک feature محدود طراحی/پیادهسازی کند و correctness، accessibility یا failure behavior مرتبط را اثبات کند.
Who it is for
Foundation
Worked baseline, explicit evidence table, safe local fixture and one guided failure probe.
Repair
Reduce to one failing contract, observe evidence, repair, then restore full case.
Experienced
Skip syntax walkthrough; require independent implementation, mutation evidence and residual-risk statement.
Prerequisites
1. First screen: a correct English sentence can still be a broken message contract
A checkout summary says “3 items selected — $1,249.50 — due Sep 18, 2026.” On the source developer’s machine it looks ordinary, so the implementation appears finished. But the sentence was assembled from fragments, the plural decision was count === 1 ? "item" : "items", the currency string was built with punctuation, and the date used an English month abbreviation. The failure is not cosmetic. The program has mixed domain values, grammatical selection, locale-sensitive formatting, and sentence order into one source-locale shortcut.
The bounded outcome of this lesson is to design one inspectable locale-aware message contract. User-visible text with variables stays a coherent message unit; plural or select decisions are delegated to locale-aware rules; numbers, currencies, dates, and times are formatted for the target locale; and the evidence is checked in contrasting locale fixtures. ICU’s long-standing MessageFormat guidance explains why translators need a complete message unit so placeholders can move with target-language grammar. [S-ICU-MSG] ICU’s formatting guidance also separates locale-neutral program data from locale-sensitive presentation. [S-ICU-FMT]
The artifact is Locale-Aware Message Contract Record v1. It must record the message key, variables, locale, expected plural/select category, formatted values, observed output, mutation result, repair, and one residual limitation. A passing teaching fixture proves the bounded contract for the supplied environment; it does not prove that every ICU, JavaScript, Java, C++, framework, or localization platform supports the same syntax and behavior.
2. Route orientation: syntax is optional knowledge; evidence is not
Foundation route: begin with the message matrix. Treat count, amount, and dueDate as locale-neutral domain values. For each locale, predict the plural category, then inspect the formatted currency and date before reading the final sentence. This keeps three different decisions visible instead of collapsing them into a single “looks translated” judgment.
Repair route: start with one deliberate regression. Replace the whole message unit with concatenated fragments, hard-code a separator, or reduce plural logic to English one/other. Predict which evidence dimension should fail, run the checks, and repair only that boundary. A repair is not accepted because the source locale still looks correct.
Experienced route: review the fixture as a localization contract. Ask whether translators can reorder placeholders, whether selection is locale-aware, whether display values come from locale-sensitive formatters, whether the runtime/version claim is explicit, and whether evidence covers contrasting locales. You may compress the tutorial, but you may not skip mutation, transfer, or residual-risk evidence.
3. Mental model: one message pipeline, several independent contracts
Keep the pipeline explicit:
domain value → locale + message key → message selection → locale formatter → rendered text → locale-fixture evidence
The message-unit contract owns grammatical context. A complete user-facing sentence or phrase remains together so a translator can move placeholders. ICU warns against concatenating translatable fragments because translators lose the surrounding grammar and cannot reliably rearrange the pieces. [S-ICU-MSG]
The selection contract owns grammatical alternatives. Plural categories are locale data, not an English grammar shortcut. A language can require categories that are absent in English, and the same numeric value can select differently under different rules. Use the runtime’s locale-aware plural mechanism rather than inventing one/many logic.
The formatter contract owns presentation of values. Domain numbers and timestamps remain machine-meaningful values; display strings are derived for a locale. ICU’s formatting APIs exist specifically to make number, currency, date, time, and message presentation locale-sensitive while keeping code and data separable. [S-ICU-FMT]
The version boundary owns compatibility claims. Unicode MessageFormat—the successor historically called MessageFormat 2—is now a stable part of UTS #35, but implementation surfaces still differ by runtime and version. ICU’s MessageFormatter documentation is still explicitly implementation/version scoped. Therefore “the spec is stable” does not mean “every library accepts the same syntax today.” [S-MF2]
4. Foundation layer: coherent messages before clever formatting
Suppose the source code constructs prefix + formattedCount + noun + suffix. Even if every fragment is translated, the translator can only replace fragments, not redesign the sentence around the variable. German may want the date earlier. Arabic may need different plural variants. Another language may place a currency or noun in a different grammatical relationship. The safe default is not “more fragments”; it is one translatable message unit with placeholders.
A coherent unit does not mean business data becomes text. Keep count = 3, amount = 1249.5, and dueDate = 2026-09-18 as typed values. The message layer receives these values plus locale and message key. Formatters produce locale-specific display forms at the edge. This keeps calculations, transport, storage, and comparison independent from how users see the value.
Do not parse a localized display string back into the domain model as the normal data contract. A string such as 1.249,50 € is presentation, not a portable numeric serialization. The same separation applies to dates: a user-facing localized date is not a safe substitute for an ISO-like domain representation.
5. Deep explanation: plural/select is data-driven grammar, not two branches
English examples encourage a dangerous mental model because one and other often seem sufficient. That model is not universal. A locale-aware plural system selects categories according to locale rules. Your code should provide the numeric operand and locale, then let the platform choose the category. The message resources must contain the variants needed by the target locale and a safe fallback according to the chosen message system.
This lesson’s local fixture uses Intl.PluralRules only as a deterministic teaching primitive. That does not make it a complete ICU MessageFormat implementation. The lab deliberately separates contract evidence from syntax compatibility evidence. It proves that plural category selection, coherent message resources, and locale formatters behave as expected for three supplied locales. If your product uses ICU4J, ICU4C, a JavaScript MessageFormat library, or Unicode MessageFormat directly, you must additionally test the actual runtime/library version.
Select-style decisions follow the same discipline. If a message varies by a fixed keyword such as plan type or status, the selection belongs in the message contract rather than in concatenated sentence fragments. Selection keys are program data; each selected branch is still a complete translatable message pattern.
6. Worked example: checkout summary across English, German, and Arabic
The learner fixture starts from the same domain record for all locales: an item count, USD amount, and UTC due date. For en-US, the runtime might format the amount with a dollar sign and comma grouping; for de-DE, separators and symbol placement differ; for ar-EG, digits, punctuation, directionality, and plural category behavior can differ again. The exact output is runtime data and must be observed, not copied from an article.
The evidence row stores six things separately: raw domain values, selected plural category, formatted amount, formatted date, final message, and residual limitation. This makes a failure diagnosable. If the plural category is correct but the currency string is hard-coded, the formatter contract failed. If formatted values are correct but the final Arabic sentence uses the English fragment order, the message-unit contract failed. If all three supplied locales pass, the evidence still says only that those fixtures passed in the recorded runtime.
A strong evidence statement looks like: “In Node runtime X, Intl.PluralRules('ar-EG') selected the recorded category for the supplied count; the resource branch existed; Intl.NumberFormat and Intl.DateTimeFormat produced the observed display values; the assembled output came from one locale-owned template.” The inference is narrower: “The bounded fixture preserves the required contract for this runtime and case set.”
7. Failure modes: shortcuts that survive a source-locale demo
Fragment concatenation. The English output remains readable, so the bug hides until a translator needs a different order. The mutation should fail even if visual output accidentally matches one locale.
English-only plural branching. count === 1 is treated as singular and everything else as plural. The shortcut silently collapses categories required elsewhere. A contrasting locale fixture exposes the missing branch.
Hard-coded display punctuation. A developer inserts comma grouping, decimal point, currency symbol, or month names by hand. The value becomes source-locale presentation disguised as data.
Implicit locale. The developer omits the locale and relies on the machine default. A test can pass locally and change on another environment. The contract should record the effective locale explicitly.
Version overclaim. A developer reads a current Unicode MessageFormat example and assumes the same syntax is accepted by the deployed library. Specification maturity and implementation support are different facts. Record runtime, library, and version before claiming compatibility.
Single-locale evidence. Passing English proves only English. Localization correctness requires contrast. The evidence matrix therefore includes at least English, German, and Arabic in the teaching fixture.
8. Experienced bridge: from i18n APIs to an auditable contract
Experienced engineers often know Intl.NumberFormat, CLDR, ICU, or framework i18n APIs already. The deeper skill is to make the contract reviewable. A code review should be able to answer: Where is the complete translatable message? Which variables enter it? What selects the branch? Which formatter owns each display value? What exact runtime interprets the message syntax? Which locale cases were observed? What failure mutation was detected?
This framing prevents architecture labels from acting as evidence. “We use ICU” is not enough. ICU contains multiple APIs and versions. “We use MessageFormat 2” is not enough unless the runtime and implementation are named. “We use locale-aware formatters” is not enough unless the effective locale and observed output are recorded.
For production work, add the product’s real localization pipeline, extraction tooling, translator workflow, and QA coverage. Those concerns connect to the next lesson’s localization data model and terminology governance; they are not absorbed here.
9. Alternatives and trade-offs: choose mechanisms by contract
Legacy ICU MessageFormat remains widely relevant and has mature message-pattern guidance. Unicode MessageFormat provides a newer standardized data model and syntax. Framework-specific i18n libraries can wrap one of these ideas or implement their own message layer. The correct choice depends on the deployed runtime, translator tooling, extraction pipeline, ecosystem support, and migration constraints.
The lesson does not prescribe one universal library. It prescribes evidence boundaries. A mechanism is acceptable when it keeps messages coherent, delegates locale-sensitive decisions correctly, formats values for the target locale, makes the implementation/version explicit, and can be verified with contrasting locale fixtures. If a library cannot satisfy one of those dimensions, the decision record must explain the limitation rather than hiding it behind a familiar API name.
10. Guided and independent practice
Guided task: run the baseline fixture. Before executing it, predict the category and visible formatting differences you expect for en-US, de-DE, and ar-EG. Record observed categories and formatted values. Then run a mutation that disables the message-unit requirement or removes an Arabic plural branch. The audit should fail with a specific contract code. Repair the fixture and rerun.
Independent task: the changed context is a subscription renewal notice. It adds a plan name, renewal date, price, and count-sensitive seat message for a new locale. Do not copy checkout wording. Reapply the method: define the message unit, variables, locale, selection rule, formatters, evidence cases, version boundary, and residual limitation. Your implementation may differ; the evidence method must remain intact.
11. Verification and evidence: separate observation from inference
The Locale-Aware Message Contract Record v1 contains rows for the bounded cases. Each row names the locale, input values, selected category, formatted values, rendered message, and evidence source. Mutation entries include the predicted failure, observed issue code, diagnosis, repair, and rerun result. The transfer section states whether the learner solved the renewal scenario independently.
Observation: “The audit emitted PLURAL_CATEGORY_COVERAGE after the Arabic few branch was removed.” Inference: “The resource set no longer covers a category required by the supplied Arabic fixture.” Decision: “Restore the locale-owned branch and rerun.” Residual limitation: “This fixture does not prove translator quality, every locale, or compatibility with an untested ICU/MessageFormat implementation.”
That structure matters because localization bugs are easy to explain after the fact. Evidence forces the claim to be testable before acceptance.
12. Assessment and transfer
You should be able to state the core contract and one non-goal, implement the bounded feature, diagnose a deliberate failure, defend the chosen mechanism against a plausible alternative, and transfer the method to a different message without decisive scaffolding. Blocking failures are: a critical mutation goes undetected, API vocabulary is used as the only proof, a hard prerequisite is ignored, or the evidence claims compatibility that was never tested.
The final accountable judgment remains human. AI can propose candidate checks after you state the contract, but it cannot invent observed locale output, translator feedback, runtime support, or acceptance evidence.
13. References and freshness
S-ICU-MSG — ICU Formatting Messages documentation: coherent user-visible messages, translator reordering, plural/select behavior, and the distinction between long-standing MessageFormat and newer successor work. [S-ICU-MSG]
S-ICU-FMT — ICU Formatting and Parsing documentation: locale-sensitive formatting for numbers, currencies, dates, times, and messages, with separation between program data and localized presentation. [S-ICU-FMT]
S-MF2 — Unicode MessageFormat documentation: current successor syntax/data model and version-bounded integration surface. Current freshness review records that the Unicode MessageFormat specification is stable in UTS #35 Part 9, while concrete runtime/library support must still be checked separately. [S-MF2]
Freshness boundary: the authority set is unchanged from the Bible. Re-review is due 2026-10-17 or earlier if official guidance, specification status, or the lab/runtime behavior changes. This lesson does not claim universal production support for one syntax across all implementations.
Assessment
There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.
WEB-020-S1 retrieval
State the locale-aware message contract: coherent message units, locale-aware plural/select and explicit locale-sensitive value formatting; name one non-goal.
WEB-020-S2 application
Implement the bounded locale-aware fixture across en-US, de-DE and ar-EG using explicit locale-aware plural, number/currency and date formatting, then complete the evidence record.
WEB-020-S3 diagnosis
Predict, run, diagnose and repair one deliberate mutation affecting message-unit placeholders, plural categories, locale binding, formatter behavior, MF version boundary or evidence integrity.
WEB-020-S4 decision
Defend the chosen message/formatter mechanism against a plausible shortcut and state the runtime/version boundary and residual limitation.
WEB-020-S5 transfer
Independently solve the subscription-renewal changed-context case for pl-PL with plan name, renewal date, price and count-sensitive seats without copying checkout wording.
Assessment rubric
Critical dimensions:
- MESSAGE_UNIT — Variable-bearing learner-visible text remains one coherent translatable message unit; unsafe concatenation fails.
- PLURAL_SELECT — Plural/select behavior is delegated to locale-aware rules; an English one/many shortcut is not universal evidence.
- LOCALE_FORMATTERS — Number/currency/date formatting is explicitly locale-sensitive while domain values remain locale-neutral.
- MF_VERSION_BOUNDARY — Stable Unicode MessageFormat specification status is kept distinct from runtime/library implementation support; actual runtime/version claims must be bounded.
- EVIDENCE_MATRIX / TRANSFER — Contrasting locale fixtures, mutation/repair and an independent changed-context transfer are required; deterministic Node Intl evidence does not prove universal ICU or MF2 runtime support.
Blocking assessments: S2, S3 and S5. S1 and S4 are non-blocking but must preserve the observation/inference and runtime/version boundaries.
The internal synthetic oracle is admin/audit material and is not published as learner evidence.
References & freshness
Case studies
Lab files
Lesson media & slides
Teaching files (download)