Jūsų Lovable programėlė gali būti visiškai išversta, bet vis tiek rodyti „5 элемент“ arba rodyti kainą kaip „1,234.50“ vokiečių kalbos naudotojui. Priežastis — daugiskaitos ir formatavimo logika, parašyta anglų kalbai ir palikta komponentuose. globalize.now — dirbtiniu intelektu grįsta lokalizacijos infrastruktūra, kuri laiko jūsų eilutes įkeltuose kataloguose. Toliau aprašytas sprendimas daugiskaitos taisykles perkelia į šiuos katalogus, o ne į jūsų kodą.

Kodėl Lovable verčiant programėlę sugenda daugiskaita?

Todėl, kad daugiskaitos taisyklė yra komponente, o ne vertime. Įprastas sugeneruotas šablonas atrodo taip:

<p>{count} {count === 1 ? "item" : "items"} in your cart</p>

Ši eilutė užkoduoja anglų kalbos gramatiką. Vertėjas gali pakeisti žodžius, bet ne === 1 sąlygą, be to, žodžių tvarka taip pat fiksuota — skaičius visada pirmas. Anglų kalba turi dvi formas. Rusų kalba — keturias, todėl „1 элемент“, „2 элемента“, „5 элементов“ ir „1,5 элемента“ visi reikalauja skirtingų galūnių.

Jei pirmiausia sukonfigūravote maršrutizavimą (žr. kaip padaryti Lovable programėlę daugiakalbę), kita klaida, kurią pastebi naudotojai, yra daugiskaita, nes niekas nesustoja veikti. Tiesiog sakinys būna neteisingas.

1 žingsnis: kaip užrašyti daugiskaitą, kurią vertėjai galėtų keisti?

Naudokite ICU daugiskaitos pranešimą, kad taisyklė persikeltų į vertimą. Su Lingui jį sukuria ir Plural komponentas, ir plural makrokomanda.

import { Plural } from "@lingui/react/macro";

<p>
  <Plural value={count} one="# item in your cart" other="# items in your cart" />
</p>

Eilutėms už JSX ribų naudokite makrokomandą iš core paketo:

import { plural } from "@lingui/core/macro";

const label = plural(count, { one: "# file", other: "# files" });

# pakeičiamas skaičiumi. Pagal Lingui dokumentaciją, rašote tik tas formas, kurių reikia jūsų šaltinio kalbai, o other yra privaloma. Tikslios reikšmės, tokios kaip _0="Your cart is empty", anglų kalboje apdoroja nulio atvejį be atskiros šakos.

Lovable numatytieji technologijų rinkiniai skiriasi konfigūracija, bet ne šia API, todėl tas pats komponentas veikia ir Vite SPA, ir TanStack Start projektuose.

Kaip atrodo katalogas, kai daugiskaitos jau ištrauktos?

Vienas pranešimas kiekvienai eilutei, standartine ICU sintakse, saugomas kaip PO failas jūsų saugykloje. Vertėjas, žmogus ar dirbtinis intelektas, pateikia formas, kurių reikia jo kalbai.

msgid "{count, plural, one {# item in your cart} other {# items in your cart}}"
msgstr "{count, plural, one {# товар в корзине} few {# товара в корзине} many {# товаров в корзине} other {# товара в корзине}}"

Rusų kalbos other forma apima trupmenas, pavyzdžiui, 1,5, todėl ji sutampa su kilmininko linksnio vienaskaita. Kadangi katalogas yra commit'intas failas, daugiskaitos pakeitimus peržiūrite pull request'e kaip ir bet kokį kitą kodą. Apie pačią sintaksę žr. kas yra ICU MessageFormat.

Kurioms kalboms reikia daugiau nei one ir other?

Unicode CLDR apibrėžia šešias daugiskaitos kategorijas: zero, one, two, few, many ir other. Kiekviena kalba naudoja jų pogrupį, o other privaloma visur.

KalbaNaudojamos kategorijos
japonų, kinųother
Anglųone, other
Rusųone, few, many, other
Arabųzero, one, two, few, many, other

CLDR specifikacijoje nurodyta, kad velsiečių kalba taip pat naudoja visas šešias. Šito mintinai mokytis nereikia. Reikia katalogo formato, kuris leistų kiekvienai kalbai užpildyti savo formas, o PO su ICU pranešimais būtent tai ir leidžia.

Kaip padaryti, kad Lovable daugiau nebegeneruotų ternary daugiskaitos?

Taisyklę įrašykite ten, kur Lovable skaito nurodymus. Lovable perkuria komponentus, kai prašote naujų funkcijų, o nauja funkcija, parašyta be taisyklės, sugrąžina ternary operatorių.

Įrašykite tai į savo Knowledge arba AGENTS.md:

Never hand-build plurals or number formats. Use the Lingui Plural component
or plural() macro for every count. Use Intl with the active locale for every
date, number and price.

lovable-i18n skill rašo tokias taisykles už jus. Kaip jis tai daro, aprašyta ką daro Lovable i18n skill. Po kitos sugeneruotos funkcijos diff'e suraskite === 1 ir !== 1, kad įsitikintumėte, jog taisyklės laikomasi.

2 žingsnis: kaip formatuoti datas ir valiutas pagal lokalę?

Naudokite Intl su aktyvia lokale. Lingui objektas i18n taip pat siūlo i18n.date() ir i18n.number(), bet tiesiogiai kviečiant Intl su i18n.locale, formatavimo parametrai lieka matomi jūsų pačių kode.

import { useLingui } from "@lingui/react";

export function Price({ amount, currency }: { amount: number; currency: string }) {
  const { i18n } = useLingui();
  return (
    <span>
      {new Intl.NumberFormat(i18n.locale, { style: "currency", currency }).format(amount)}
    </span>
  );
}

export function OrderDate({ date }: { date: Date }) {
  const { i18n } = useLingui();
  return <time>{new Intl.DateTimeFormat(i18n.locale, { dateStyle: "long" }).format(date)}</time>;
}

Tie patys 1234,5 euro kiekvienoje lokalėje atvaizduojami kitaip — su savais skyrikliais ir simbolio padėtimi. Formatavimas niekada nekonvertuoja pinigų. Eurais saugoma kaina visomis kalbomis lieka eurais, todėl duomenų bazėje šalia kiekvienos kainos laikykite valiutos kodą.

3 žingsnis: kaip prieš išleidžiant patikrinti visas daugiskaitos kategorijas?

Paklauskite naršyklės, į kokią kategoriją patenka skaičius, ir patikrinkite, ar kiekviena turi formą.

const ru = new Intl.PluralRules("ru");
[1, 2, 5, 21, 1.5].map((n) => ru.select(n));
// ["one", "few", "many", "one", "other"]

const ar = new Intl.PluralRules("ar");
[0, 1, 2, 3, 11, 100].map((n) => ar.select(n));
// ["zero", "one", "two", "few", "many", "other"]

Pridėkite po vieną testą kiekvienai išleidžiamai kalbai: atvaizduokite komponentą su skaičiumi iš kiekvienos kategorijos ir patikrinkite, kad nė viena nenukrenta į trūkstamą formą. Tada kartą peržiūrėkite rusų ir arabų puslapius naršyklėje. Trūkstamas few kataloge pasimato kaip neteisinga galūnė, o ne kaip klaida.

Kas pasikeičia, jei anksčiau naudojau vykdymo metu veikiantį valdiklį?

Vykdymo metu veikiantys valdikliai verčia jau atvaizduotą tekstą po įkėlimo, todėl nemato jūsų kode esančios daugiskaitos taisyklės. Tai viena iš priežasčių, kodėl svarbu perkelti vertimus į saugyklą. Lovalingo veikla baigėsi 2026-08-31; perėjimo vadove ir palyginimo puslapyje aprašyta, kas pasikeičia, kai katalogai laikomi jūsų saugykloje.

Naudodami globalize.now, saugyklą prijungiate vieną kartą, o kodo bazė programėlėje konvertuojama. Po to push užduotys išverčia naujus katalogo vienetus, o rezultatas pateikiamas kaip pull request. Lovable sinchronizuojasi iš GitHub, todėl daugiskaitos formos į jūsų programėlę patenka taip pat, kaip ir bet kuris kitas pakeitimas. Nustatymai aprašyti Lovable integracijos puslapyje, o darbo eiga be valdymo skydelio — kaip lokalizuoti Lovable programėlę be valdymo skydelio.

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