ICU MessageFormat yra Unicode standartas, skirtas rašyti vieną verčiamą eilutę, kuri prisitaiko prie skaičiaus, giminės ir kitų kintamųjų. Jį vis dar sunku versti, nes sintaksė buvo sukurta kodui, o ne žmonėms, kurie lokalizuoja tekstą. Specifikacija egzistuoja gerokai daugiau nei dešimtmetį, o dažniausiai su ja suklysta netechniniai vertėjai, žiūrintys į įdėtus riestinius skliaustus. globalize.now yra DI pagrįsta lokalizavimo infrastruktūra, veikianti vienu sluoksniu žemiau šios problemos: ji ištraukia eilutes ir sugeneruoja lokalės failus, kuriuose laikomi šie ICU šablonai, o tada po kiekvieno Git push palaiko juos sinchronizuotus.

Kas yra ICU MessageFormat?

ICU MessageFormat yra sintaksė, skirta išreikšti pranešimą, kurio galutinė formuluotė priklauso nuo vykdymo metu gaunamų duomenų. Užuot jungę kodo fragmentus, parašote vieną šabloną, o formatuoklis pagal lokalę parenka tinkamą šaką.

Dažniausiai jis naudojamas daugiskaitai:

{count, plural,
  one {You have # message}
  other {You have # messages}
}

# pakeičiamas skaičiumi, o one / other šakos atitinka kalbos daugiskaitos kategorijas. Anglų kalboje jų yra dvi, o lenkų, rusų ir arabų kalbose — daugiau. ICU taip pat apdoroja giminę ir kitus pasirinkimus naudodamas select:

{gender, select,
  male {He liked your post}
  female {She liked your post}
  other {They liked your post}
}

Todėl ICU tapo de facto daugiskaitos standartu: gramatinis sudėtingumas perkeliamas į duomenis, kurie gali skirtis pagal kalbą, o ne į šakojimosi logiką, veikiančią tik tai kalbai, kuria ji parašyta. Vykdymo bibliotekos, tokios kaip FormatJS, i18next ir next-intl, jį supranta.

Kodėl ICU MessageFormat taip sunku versti?

Jį sunku versti, nes sintaksė sukurta kūrėjams, o žmonės, kurie iš tikrųjų verčia eilutes, dažniausiai nėra kūrėjai.

Atidaręs lokalės failą vertėjas nemato „Jūs turite 3 pranešimus“. Jis mato riestinius skliaustus, raktinius žodžius plural ir select, galbūt neatpažįstamas daugiskaitos kategorijas ir # vietaženklį, kuris atrodo kaip rašybos klaida. Ištrynus vieną skliaustą arba pervadinus vieną kategoriją, eilutė vykdymo metu sukelia klaidą, užuot buvusi atvaizduota. Struktūra, dėl kurios ICU yra galingas inžinieriams, yra ta pati struktūra, dėl kurios jis tampa trapus lingvisto rankose.

Tai spraga, su kuria lokalizavimo pramonė tyliai gyvena jau daugelį metų. Dauguma įrankių ją sprendžia rodydami neapdorotą šabloną ir tikėdamiesi, kad vertėjas nepakeis netinkamo simbolio, arba slėpdami daugiskaitos formas atskirame redaktoriuje, kuriame vertėjas vis tiek turi suprasti daugiskaitos kategorijas. Nė vienas tiekėjas iki galo nesumažino atotrūkio tarp specifikacijos sudėtingumo ir netechninio vertėjo mąstymo modelio.

Kas pasikeitė atsiradus MessageFormat 2.0?

MessageFormat 2.0 yra nuo pagrindų pertvarkyta sintaksė, o 2025 m. ji tapo stabiliu standartu, o ne juodraščiu.

MF2 2025 m. kovą pasiekė galutinio kandidato statusą ir dabar yra stabili CLDR dalis, paskelbta kaip Unicode LDML techninio standarto dalis bei tobulinama LDML 47 ir 48 leidimuose. Etaloninė realizacija atitinka specifikaciją pagal 2026 m. pradžioje išleistą LDML 48.2 versiją. Naujoji sintaksė atskiria įvestis nuo atitikties logikos ir palaiko įvardytas formatavimo funkcijas, todėl sudėtingi pranešimai tampa lengviau skaitomi:

.input {$count :number}
.match $count
one {{You have {$count} message}}
*   {{You have {$count} messages}}

Siekiama sukurti šabloną, kurį būtų lengviau plėsti ir kuris būtų šiek tiek mažiau nedraugiškas skaitant nei originalūs įdėti skliaustai.

Ar MessageFormat 2.0 išsprendžia vertėjų problemą?

Dar ne — dėl dviejų priežasčių.

Pirma, MF2 pagerina sintaksės naudojimo patogumą, tačiau ji vis tiek lieka sintaksė. Vertėjas vis dar susiduria su .match, daugiskaitos raktais ir skliaustais. Kognityvinė apkrova mažesnė nei naudojant MF1, bet ji neišnyko, todėl netechninis vertėjas vis dar gali sugadinti pranešimą redaguodamas ne tą vietaženklį.

Antra, produkcijoje jį naudoja beveik niekas. Įsisavinimas iki pat 2026 m. išlieka ribotas: JavaScript dalies TC39 procesas reikalauja, kad prieš tolesnę pažangą maždaug keliolika organizacijų naudotų MF2 produkcijoje, tačiau ši riba dar nepasiekta. Praktiškai dauguma šiandien leidžiamų programų vis dar naudoja originalų ICU MessageFormat per tokias bibliotekas kaip FormatJS ir i18next. Taigi vertėjams skirta problema neišsprendžiama specifikacija — ją išsprendžia vieta, kurioje sintaksė sukuriama ir prižiūrima.

Kur ICU MessageFormat sugenda DI sugeneruotose programose?

Jis sugenda anksti, nes DI programavimo įrankiai retai iš karto sugeneruoja taisyklingą ICU.

Kurdami su Cursor, Claude Code arba Lovable, sugeneruotame kode skaičiai dažniausiai apdorojami naiviai:

// What an AI coding tool often generates
const label = count + " " + (count === 1 ? "message" : "messages");

Ši logika teisinga anglų kalbai, tačiau netinka daugumai kitų kalbų, nes daro prielaidą, kad yra lygiai dvi daugiskaitos formos. Be to, sakinys įrašomas į programos kodą, todėl lokalės faile apskritai nėra ICU šablono, kurį vertėjas galėtų lokalizuoti. Eilutė lieka nematoma lokalizavimo sluoksniui, kol kas nors produkcijoje nepastebi sugadintos gramatikos. DI įrankiai taip pat dubliuoja raktus ir išmėto kietai įrašytą tekstą po komponentus, todėl net komandos, norinčios naudoti ICU, galiausiai turi eilučių, kurios niekada nepateko į verčiamą failą. globalize.now kūrėjams skirta apžvalga sukurta būtent tam, kad tokio tipo eilutės būtų aptiktos prieš joms patenkant į produkciją.

Kaip kūrėjai turėtų naudoti ICU MessageFormat 2026 m.?

Laikykite ICU sugeneruota infrastruktūra, o ne rankiniu būdu kuriamu turiniu.

Praktinė taisyklė: kūrėjai ir DI įrankiai neturėtų programiniame kode kurti daugiskaitos jungdami eilutes, o vertėjai neturėtų rankiniu būdu redaguoti neapdorotų ICU skliaustų. ICU šablonas turi būti lokalės faile, kuris automatiškai sugeneruojamas ir nuolat atnaujinamas, o vykdymo metu atvaizduojamas naudojant tokią biblioteką kaip FormatJS, i18next ar next-intl. Taip sintaksė išlieka taisyklinga nuo pat sukūrimo ir nuosekli visose lokalėse keičiantis programai. Jei svarstote, kaip ICU dera su jūsų vykdymo sluoksniu, globalize.now ir i18next palyginime paaiškinama, kaip infrastruktūra ir vykdymo aplinka pasidalija darbą.

Būtent šiame sluoksnyje veikia globalize.now. Jis ištraukia iš jūsų kodų bazės joje įrašytas eilutes, sugeneruoja raktus ir lokalės failus, kuriuose saugomi ICU šablonai, ir iš naujo juos sinchronizuoja po kiekvieno Git išsiuntimo, todėl struktūra išlieka taisyklinga be rankinio eksportavimo. globalize.now nesiekia būti vertėjo redaktoriumi ir nepakeičia jūsų vykdymo bibliotekos — jis užtikrina, kad ICU struktūros failai, nuo kurių priklauso šie įrankiai, iš tikrųjų egzistuotų ir būtų sinchronizuoti. „Vibe coding“ kūrėjų vadove tas pats procesas paaiškinamas programoms, sukurtoms naudojant Lovable, Bolt ir Replit, o platesnė eiga pateikiama globalize.now pagrindiniame puslapyje.

globalize.now paverčia užkoduotą programos tekstą į vertimui paruoštus lokalės failus ir juos atnaujina, kai jūs diegiate naujus pakeitimus.

Išbandyti globalize.now nemokamai