Ţŕàñšļàţîñĝ ŵîţĥ kapi
neokapi-i18n þŕöđüçéš à KBF đîŕéçţöŕý àŕçĥîṽé. Ţĥé kapi ÇĻÎ ţŕàñšļàţéš îţ. Ţĥîš þàĝé ŵàļķš ţĥŕöüĝĥ ţĥé ţĥŕéé ḿöšţ üšéƒüļ ƒļöŵš.
Þšéüđö-ţŕàñšļàţîöñ ƒöŕ ÜÎ çĥéçķš
Þšéüđö-ţŕàñšļàţîöñ îš ţĥé ƒàšţéšţ ŵàý ţö šéé ŵĥàţ ĥàš ƃééñ þîçķéđ üþ ƒöŕ ţŕàñšļàţîöñ, àñđ ŵĥàţ ĥàš ñöţ.
kapi pseudo-translate i18n/
Ŵîţĥ ñö -o, ţĥé đéƒàüļţ ƒöŕ KBF îñþüţš îš îñ-þļàçé: ţĥé qps ţàŕĝéţ îš àđđéđ ţö ţĥé šàḿé àŕçĥîṽé. Ŕüñ àĝàîñ ŵîţĥ --target-lang fr ţö àđđ àñöţĥéŕ ļöçàļé; ţĥé ŵŕîţéŕ îš ļöçàļé-àđđîţîṽé àñđ éẋîšţîñĝ ţàŕĝéţš šţàý þüţ.
Šöüŕçé Welcome to Acme ƃéçöḿéš ▒ Ŵéḷçőḿé tő Âçmé ▒:
- Àççéñţéđ çĥàŕàçţéŕš ḿàķé ţŕàñšļàţéđ šţŕîñĝš ṽîšüàļļý đîšţîñçţ. Üñţŕàñšļàţéđ šţŕîñĝš (ƃüĝš) šţàñđ öüţ îḿḿéđîàţéļý îñ ţĥé ÜÎ.
- Ḿàŕķéŕš (
▒) ḿàŕķ šţàŕţ àñđ éñđ, šö ţŕüñçàţîöñ îš öƃṽîöüš (Welcome to Ac…ñéṽéŕ ŵŕàþš ţö▒ Ŵéḷç…). - Éẋþàñšîöñ (àđđîñĝ 30–50% ḿöŕé çĥàŕàçţéŕš) ḿîḿîçš Ĝéŕḿàñ, Ƒŕéñçĥ àñđ Ŕüššîàñ šţŕîñĝ ĝŕöŵţĥ šö ļàýöüţ ƃüĝš šüŕƒàçé ƃéƒöŕé ýöü šĥîþ.
Ţĥéñ neokapi-i18n compile îţ àñđ ļöàđ îţ àš àñý öţĥéŕ ļöçàļé:
neokapi-i18n compile i18n/ --out public/translations
Ýöüŕ đéṽ šéŕṽéŕ ñöŵ ĥàš à qps ļöçàļé. Ŵîŕé à ļàñĝüàĝé þîçķéŕ àñđ šĥîþ þšéüđö-ţŕàñšļàţéđ šçŕééñšĥöţš ţö đéšîĝñ ŕéṽîéŵ.
Þšéüđö-ţŕàñšļàţîöñ îñ ÇÎ
Àđđ îţ ţö ÇÎ àš à ÜÎ-ļàýöüţ šḿöķé ţéšţ:
- run: vp neokapi-i18n extract
- run: kapi pseudo-translate i18n/
- run: vp neokapi-i18n compile i18n/ --out public/translations
- run: npm run test:e2e # runs against ?locale=qps
ÀÎ ţŕàñšļàţîöñ
Ƒöŕ àçţüàļ ţŕàñšļàţîöñš, kapi translate ƒééđš ţĥé KBF đîŕéçţöŕý ţĥŕöüĝĥ àñ ĻĻḾ. Îţ þŕéšéŕṽéš þļàçéĥöļđéŕš, îñļîñé éļéḿéñţ ţöķéñš, àñđ þļüŕàļ / šéļéçţ šţŕüçţüŕé:
kapi translate i18n/ --target-lang fr
kapi translate i18n/ --target-lang de
kapi translate i18n/ --target-lang ja
Éàçĥ çàļļ àççüḿüļàţéš à ţàŕĝéţ ļöçàļé îñ þļàçé. Ţö ŕéđîŕéçţ öüţþüţ ţö à đéŕéñţ ƒîļé, þàšš -o target-dir/; ţĥé îñþüţ šţàýš üñţöüçĥéđ.
kapi šüþþöŕţš Àñţĥŕöþîç, ÖþéñÀÎ, Ĝööĝļé Ĝéḿîñî, Àžüŕé ÖþéñÀÎ, àñđ ļöçàļ Öļļàḿà ḿöđéļš. Šéļéçţ ţĥé þŕöṽîđéŕ (àñđ öþţîöñàļļý ţĥé ḿöđéļ) ŵîţĥ ƒļàĝš, öŕ îñ à ƒļöŵ'š šţéþ çöñƒîĝ:
kapi translate i18n/ --target-lang fr --provider anthropic
ÀÞÎ ķéýš àŕé ñéṽéŕ ŵŕîţţéñ îñţö ţĥé çöḿḿîţţéđ ŕéçîþé. Šüþþļý öñé, îñ þŕéçéđéñçé öŕđéŕ, ŵîţĥ --api-key, à šàṽéđ ķéýçĥàîñ çŕéđéñţîàļ (kapi credentials add, ţĥéñ --credential <name>), öŕ ţĥé þŕöṽîđéŕ'š šţàñđàŕđ éñṽîŕöñḿéñţ ṽàŕîàƃļé (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, …). Ļöçàļ Öļļàḿà ñééđš ñö ķéý.
Šéé Ţŕàñšļàţîöñ ƒöŕ ţĥé ƒüļļ þŕöṽîđéŕ àñđ çöñƒîĝüŕàţîöñ šüŕƒàçé.
Çöñţéẋţ çàŕŕîéš ţĥŕöüĝĥ
Éṽéŕý ƃļöçķ îñ ţĥé KBF đîŕéçţöŕý çàŕŕîéš îţš éļéḿéñţ ("button", "p", …), îţš ƒîļé àñđ ļîñé, îţš çöḿþöñéñţ ñàḿé, àñđ àñý data-i18n-note àññöţàţîöñ. Ţĥé ÀÎ ţŕàñšļàţöŕ ĝéţš ţĥàţ çöñţéẋţ àš þàŕţ öƒ ţĥé þŕöḿþţ, šö à <button>Close</button> ĝéţš à đéŕéñţ ţŕàñšļàţîöñ ţĥàñ àñ <a>Close</a> îñ à ļîšţ-îţéḿ'š đéļéţé àçţîöñ.
Ŵĥéŕé ţĥé éļéḿéñţ àļöñé îš ţöö ļîţţļé ţö đîšàḿƃîĝüàţé (ţŵö ƃüţţöñš ƃöţĥ ŕéàđîñĝ "Öþéñ", öñé à ṽéŕƃ àñđ öñé à šţàţé), àđđ ţĥé ñöţé éẋþļîçîţļý ŵîţĥ data-i18n-note öŕ t(text, context). Ţĥàţ ñöţé îš þàŕţ öƒ ţĥé ķéý, šö ţĥé ţŵö šţŕîñĝš šéþàŕàţé ƒöŕ ţĥé ţŕàñšļàţöŕ àñđ šţàý šéþàŕàţé.
Ţŕàñšļàţé à šüƃšéţ
Ƒöŕ îñçŕéḿéñţàļ ţŕàñšļàţîöñš (öñļý ţĥé šţŕîñĝš ţĥàţ çĥàñĝéđ), ŕé-éẋţŕàçţ îñţö ţĥé šàḿé àŕçĥîṽé àñđ ţŕàñšļàţé öñļý ţĥé üñţŕàñšļàţéđ ƃļöçķš. neokapi-i18n extract îš ļöçàļé-àđđîţîṽé, šö ŕé-ŕüññîñĝ îţ àđđš ñéŵ šöüŕçé ƃļöçķš ŵîţĥöüţ đîšţüŕƃîñĝ éẋîšţîñĝ ţàŕĝéţš; kapi exec translate --skip-matched ţĥéñ šķîþš àñý ƃļöçķ ţĥàţ àļŕéàđý ĥàš à ţàŕĝéţ ƒöŕ ţĥé ļöçàļé:
vp neokapi-i18n extract # refresh i18n/ with new/changed blocks
kapi exec translate i18n/ --target-lang fr --skip-matched
Öñļý ţĥé ƃļöçķš àđđéđ šîñçé ţĥé ļàšţ þàšš àŕé šéñţ ţö ţĥé ĻĻḾ; éṽéŕýţĥîñĝ àļŕéàđý ţŕàñšļàţéđ îš ļéƒţ àš-îš.
Çĥéçķš
kapi exec qa ŕüñš þļàçéĥöļđéŕ, îñļîñé-çöđé, ŵĥîţéšþàçé, àñđ ļéñĝţĥ çĥéçķš àĝàîñšţ à ţŕàñšļàţéđ àŕçĥîṽé; kapi exec term-check éñƒöŕçéš àþþŕöṽéđ ţéŕḿîñöļöĝý:
kapi exec qa i18n/ --target-lang fr # placeholder, code, length, consistency
kapi exec term-check i18n/ --target-lang fr --termstore terms/fr.db # terminology
qa çöṽéŕš:
- Þļàçéĥöļđéŕ àñđ îñļîñé-çöđé îñţéĝŕîţý: éṽéŕý
{name}àñđ îñļîñé-éļéḿéñţ ţöķéñ ({=m0}) îñ ţĥé šöüŕçé àþþéàŕš îñ ţĥé ţàŕĝéţ. - Ļéñĝţĥ ƃöüñđš: ƒļàĝ ţàŕĝéţš ţĥàţ ĝŕöŵ öŕ šĥŕîñķ ƃéýöñđ çöñƒîĝüŕàƃļé þéŕçéñţàĝéš öƒ ţĥé šöüŕçé (üšéƒüļ ƒöŕ ƒîẋéđ-ŵîđţĥ ÜÎ çöñţàîñéŕš).
- Çöñšîšţéñçý: đöüƃļé šþàçéš, đöüƃļéđ ŵöŕđš, ļéàđîñĝ/ţŕàîļîñĝ ŵĥîţéšþàçé, ţàŕĝéţ-îđéñţîçàļ-ţö-šöüŕçé, àñđ ḿöŕé (éàçĥ îñđîṽîđüàļļý ţöĝĝļéàƃļé).
term-check ƒļàĝš ţàŕĝéţš ţĥàţ đîṽéŕĝé ƒŕöḿ àñ àþþŕöṽéđ ţéŕḿ, ƒöŕ éẋàḿþļé à þŕöđüçţ ñàḿé ţĥàţ ḿüšţ šţàý üñţŕàñšļàţéđ. (kapi exec qa --check-terminology ƒöļđš ţĥé þŕöĵéçţ ţéŕḿš šţöŕé îñţö ţĥé çĥéçķ þàšš îñšţéàđ öƒ ŕüññîñĝ à šéþàŕàţé çöḿḿàñđ.)
Ƒîñđîñĝš çàñ ƒàîļ ýöüŕ ƃüîļđ. À çöḿḿöñ ÇÎ þàţţéŕñ îš extract → translate → qa, éẋîţîñĝ ñöñ-žéŕö öñ àñý çàţéĝöŕý ýöü ĝàţé öñ.
Çöñţéñţ ḿéḿöŕý ļéṽéŕàĝé
kapi ĥàš à ƃüîļţ-îñ ŠǪĻîţé çöñţéñţ ḿéḿöŕý. Ƒééđ þàšţ ţŕàñšļàţîöñš îñ:
kapi memory import historical-translations.tmx -s en -t fr
Ţĥéñ þŕé-ƒîļļ ḿàţçĥéš ƃéƒöŕé ţĥé ÀÎ þàšš: kapi exec recycle ŵŕîţéš éẋàçţ àñđ ĥîĝĥ-šçöŕîñĝ ƒüžžý ḿàţçĥéš îñţö ţĥé ţàŕĝéţ, àñđ kapi exec translate --skip-matched ţŕàñšļàţéš öñļý ŵĥàţ'š ļéƒţ:
kapi exec recycle i18n/ --target-lang fr # fill targets from the project content memory
kapi exec translate i18n/ --target-lang fr --skip-matched
Þàšš --memory <name-or-path> ţö kapi exec recycle ţö đŕàŵ öñ à šþéçîƒîç çöñţéñţ ḿéḿöŕý. Šéé Çöñţéñţ ḿéḿöŕý ƒöŕ ţĥé ḿàţçĥ àñđ ƒîļļ ţĥŕéšĥöļđš.
Ţéŕḿîñöļöĝý çöñšîšţéñçý
Ƒöŕ àþþš ŵîţĥ à ļàŕĝé þŕöđüçţ ṽöçàƃüļàŕý, ķééþ ţéŕḿš ŕéñđéŕéđ çöñšîšţéñţļý ŵîţĥ à ţéŕḿš šţöŕé. Îḿþöŕţ ţĥé ţéŕḿ ļîšţ îñţö à ñàḿéđ šţöŕé, ţĥéñ ĝàţé ţŕàñšļàţîöñš ŵîţĥ kapi exec term-check šö àñý ţàŕĝéţ ţĥàţ đîṽéŕĝéš ƒŕöḿ àñ àþþŕöṽéđ ţéŕḿ îš ƒļàĝĝéđ:
kapi terms import product-terms.csv -s en -t fr --name product-terms
kapi exec term-check i18n/ --target-lang fr --termstore product-terms
Ţö ƒééđ ţéŕḿîñöļöĝý îñţö ţĥé ţŕàñšļàţîöñ šţéþ îţšéļƒ ŕàţĥéŕ ţĥàñ öñļý çĥéçķîñĝ îţ àƒţéŕŵàŕđ, ƃîñđ ţĥé šţöŕé îñ ţĥé ŕéçîþé (defaults.terms_source) öŕ ļîšţ ŕüļéš üñđéŕ term_rules: îñ ţĥé šţéþ'š çöñƒîĝ. translate ŕéàđš ţĥé ḿàţçĥîñĝ ŕüļéš îţšéļƒ àñđ šéñđš ţĥéḿ îñ ţĥé þŕöḿþţ'š ţéŕḿîñöļöĝý šéçţîöñ.
Šéé Ţéŕḿîñöļöĝý.
Þüţţîñĝ îţ ţöĝéţĥéŕ
À çöḿþļéţé Ḿàķéƒîļé / þàçķàĝé-šçŕîþţš šéţüþ ƒöŕ à ḿüļţî-ļöçàļé àþþ:
{
"scripts": {
"i18n:extract": "vp neokapi-i18n extract",
"i18n:pseudo": "kapi pseudo-translate i18n/",
"i18n:ai": "for lang in fr de ja; do kapi translate i18n/ --target-lang $lang; done",
"i18n:compile": "vp neokapi-i18n compile i18n/ --out public/translations"
}
}
Đŕîṽé îţ ƒŕöḿ à þŕöĵéçţ
Ţĥé çöḿḿàñđš àƃöṽé àŕé àđ-ĥöç: ƒļàĝš öñ éṽéŕý çàļļ, ƒîñé ƒöŕ à ǫüîçķ ŕüñ. Ƒöŕ àñ
àþþ ýöü ţŕàñšļàţé éṽéŕý ŕéļéàšé, à kapi.yaml þŕöĵéçţ ƒîļé
îš ţĥé ŵöŕķîñĝ ḿöđéļ ŵöŕţĥ àđöþţîñĝ: îţ çàþţüŕéš ţĥé çöñţéñţ þàţţéŕñš, ţàŕĝéţ
ļàñĝüàĝéš, ƒļöŵš, àñđ đéƒàüļţš öñçé, šö ýöü đŕîṽé éṽéŕýţĥîñĝ ţĥŕöüĝĥ ñàḿéđ ƒļöŵš
îñšţéàđ öƒ ŕéþéàţîñĝ ƒļàĝš, àñđ ţĥé þŕöĵéçţ šţöŕé àççüḿüļàţéš çöñţéñţ ḿéḿöŕý
àñđ ţéŕḿîñöļöĝý àçŕöšš ŕéļéàšéš.
kapi init --framework neokapi-i18n šçàƒƒöļđš ţĥé ŕéçöḿḿéñđéđ ļàýöüţ, îñ ŵĥîçĥ
éṽéŕýţĥîñĝ ţĥé šţàçķ àüţĥöŕš šîţš üñđéŕ öñé i18n/ đîŕéçţöŕý. Ţĥé ƃüñđļéŕ ŵŕîţéš
šöüŕçé çàţàļöĝš ţö i18n/src/; kapi ŵŕîţéš þéŕ-ļöçàļé ţàŕĝéţš ţö i18n/{lang}/.
Šöüŕçé ļîṽîñĝ üñđéŕ i18n/src/ (ŕàţĥéŕ ţĥàñ ƒļàţ üñđéŕ i18n/) îš ŵĥàţ ļéţš ţĥé šöüŕçé
ĝļöƃ šţàý çļéàŕ öƒ ţĥé ĝéñéŕàţéđ ţàŕĝéţš, ŵîţĥ ñö šîƃļîñĝ i18n-<lang>/ ţŕééš:
version: v1
name: MyApp
defaults:
source_language: en
target_languages: [de, fr, ja, nb]
# The terms store and the voice profile are git-tracked sources under i18n/.
voice:
profile_file: i18n/voice.yaml
terms_source: i18n/terms.json
collections:
- path: "i18n/src/**/*.kbf.json"
format: kbf
target: "i18n/{lang}/{path}.kbf.json"
i18n/
├── src/ source KBF catalogs (from `neokapi-i18n extract`)
├── de/ fr/ ja/ nb/ per-locale targets (from kapi)
├── terms.json terms store (git source)
└── voice.yaml voice profile (git source)
Ţĥé çöñţéñţ ḿéḿöŕý'š ļöçàļ šţöŕé àñđ ţĥé þšéüđö-ļöçàļé öüţþüţ àŕé ŕéƃüîļđàƃļé
šţàţé, šö ţĥéý ļîṽé üñđéŕ .kapi/work/ (ĝîţîĝñöŕéđ); ţĥé ḿéḿöŕý ƃüñđļé ţĥé
ŕéçîþé ñàḿéš îñ defaults.memory_source îš çöḿḿîţţéđ ŵîţĥ ţĥé ŕéšţ öƒ .kapi/.
Đéƒîñé à translate ƒļöŵ îñ ţĥé ŕéçîþé (ƒöŕ éẋàḿþļé recycle → translate → qa), ţĥéñ:
{
"scripts": {
"i18n:extract": "vp neokapi-i18n extract",
"i18n:translate": "kapi run translate",
"i18n:compile": "vp neokapi-i18n compile i18n/ --out public/translations"
}
}
kapi run đîšçöṽéŕš ţĥé ñéàŕéšţ kapi.yaml ŕéçîþé (öŕ þàšš -p kapi.yaml) àñđ éẋéçüţéš ţĥé ƒļöŵ ŵîţĥ ţĥé þŕöĵéçţ'š đéçļàŕéđ šöüŕçé àñđ ţàŕĝéţ ļàñĝüàĝéš àñđ đéƒàüļţš. Šéé Ƒļöŵš àñđ ţĥé þŕöĵéçţ ḿöđéļ.
Đŕîṽé îţ ƒŕöḿ Çļàüđé
Ţĥé šàḿé ƒļöŵš ŕüñ ƒŕöḿ ýöüŕ ÀÎ àššîšţàñţ. Ŵîţĥ ţĥé kapi ḾÇÞ šéŕṽéŕ
çöññéçţéđ, þöîñţ Çļàüđé àţ ýöüŕ éẋţŕàçţéđ šţŕîñĝš àñđ àšķ îţ ţö ţŕàñšļàţé àñđ çĥéçķ
ţĥéḿ. Îţ çàļļš kapi ţö ţŕàñšļàţé ţĥé KBF àŕçĥîṽé, ŕüñš ţĥé çĥéçķš, àñđ ƒîẋéš
àñýţĥîñĝ ţĥàţ ƃŕéàķš, ţĥé šàḿé àüţĥöŕ → çĥéçķ → ŕéṽîšé ļööþ ýöü'đ ŕüñ ƃý ĥàñđ:
"Ţŕàñšļàţé ţĥé šţŕîñĝš îñ
i18n/ţö Ƒŕéñçĥ àñđ Ĝéŕḿàñ, ķééþ ţĥé þļàçéĥöļđéŕš àñđ îñļîñé éļéḿéñţš îñţàçţ, ţĥéñ ŕüñ ţĥé çĥéçķš àñđ ƒîẋ àñýţĥîñĝ ţĥàţ ƒàîļš."
Çļàüđé ţŕàñšļàţéš îñ þļàçé (ļöçàļé-àđđîţîṽé), ŕüñš kapi exec qa / kapi exec term-check, àñđ
ļööþš öñ ţĥé ƒîñđîñĝš üñţîļ ţĥé àŕçĥîṽé þàššéš; ýöü neokapi-i18n compile ţĥé ŕéšüļţ àš
üšüàļ. Ýöüŕ çöḿþöñéñţš šţàý àš ţĥéý àŕé; öñļý ţĥé çàţàļöĝüé çĥàñĝéš.
Šéé Üšé ŵîţĥ Çļàüđé ƒöŕ ţĥé ḾÇÞ šéţüþ àñđ ţĥé ƃŕöàđéŕ àĝéñţ ļööþ.
Ñéẋţ
- Çöñƒîĝüŕàţîöñ: çöḿþöñéñţḾàþ, ŕüļéš, Šţöŕýƃööķ, ŵàŕñîñĝš.