Сістэма перакладу
Гэты сайт публікуецца на 17 мовах. Не камандай перакладчыкаў, а Python-скрыптам, мадэллю Claude Opus і файлавай структурай, дзе ўсё становіцца на свае месцы. Вось як гэта ўсё працуе.
Моўнае дрэва
Section titled “Моўнае дрэва”Дакументацыя знаходзіцца ў src/content/docs/. Англійская — гэта корань, а кожная іншая мова дакладна яе паўтарае:
src/content/docs/├── index.mdx ← English (root)├── getting-started.md├── features/│ ├── play-chess.md│ ├── multiplayer.md│ └── ...├── setup/│ ├── tts-overview.md│ └── ...├── under-the-hood/│ ├── architecture.md│ └── ...│├── fr/ ← French│ ├── index.mdx│ ├── getting-started.md│ ├── features/│ │ ├── play-chess.md│ │ └── ...│ └── ...│├── ja/ ← Japanese│ ├── index.mdx│ ├── getting-started.md│ └── ...│└── ... (16 language directories total)Кожны перакладзены файл — гэта структурнае адлюстраванне свайго англійскага першакрыніцы. Тая ж назва файла, той жа шлях у падкаталогу, тыя ж ключы ў frontmatter. Адзіная розніца — тэкст напісаны на іншай мове.
Чаму люстраная структура важная
Section titled “Чаму люстраная структура важная”Starlight (фрэймворк дакументацыі) абапіраецца на гэтую сіметрыю. Калі карыстальнік пераключае мову, Starlight замяняе /docs/getting-started/ на /fr/docs/getting-started/ — той жа шлях, іншы моўны прэфікс. Калі французскі файл не існуе дакладна па шляху fr/getting-started.md, пераключальнік ламаецца або моўчкі вяртаецца да англійскай.
17 моў
Section titled “17 моў”Мовы спарадкаваны паводле сусветнай папулярнасці шахмат, на аснове дадзеных з Lichess, Chess.com і рэгістрацый FIDE. Англійская ідзе першай як зыходная мова; усё астатняе ідзе паводле шахматнага рэйтынгу:
| Ранг | Код | Мова | Стыль |
|---|---|---|---|
| 1 | en | Англійская | Крыніца ісціны |
| 2 | es | Іспанская | Стандартны фармальны |
| 3 | hi | Хіндзі | Пісьмо дэванагары |
| 4 | ru | Руская | Стандартны фармальны |
| 5 | de | Нямецкая | Стандартны фармальны |
| 6 | fr | Французская | Стандартны фармальны |
| 7 | pt | Партугальская | Еўрапейская партугальская |
| 11 | pl | Польская | Стандартны фармальны |
| 12 | it | Італьянская | Стандартны фармальны |
| 13 | uk | Украінская | Стандартны фармальны |
| 14 | tr | Турэцкая | Стандартны фармальны |
| 17 | ko | Карэйская | Форма 합니다/습니다 |
| 18 | zh | Кітайская (спрошчаная) | Спрошчаныя іерогліфы |
| — | zh-tw | Кітайская (традыцыйная) | Традыцыйныя іерогліфы |
| 23 | nb | Нарвежская (букмол) | Стандартны букмол |
| — | be | Беларуская | Стандартная беларуская |
| 34 | ja | Японская | Форма です/ます |
Калонка «стыль» мае значэнне. У японскай і карэйскай ёсць фармальныя рэгістры, якія ўплываюць на кожны сказ. Промпт для перакладу ўключае гэтыя інструкцыі, каб мадэль стварала натуральны, дагледжаны тэкст — а не сухі машынны вынік.
Гэты парадак таксама вызначае выпадальны спіс моў у шапцы сайта. Найбольш распаўсюджаныя шахматныя мовы ідуць першымі, каб карыстальнікі хутчэй знаходзілі сваю без пракруткі.
Канвеер перакладу
Section titled “Канвеер перакладу”Крок 1: Напісаць на англійскай
Section titled “Крок 1: Напісаць на англійскай”Уся дакументацыя пачынаецца як англійскі markdown у src/content/docs/. Frontmatter мае title і description:
---title: "Getting Started"description: "Install En Parlant~ and play your first game."---
Download the latest release...Крок 2: Запусціць скрыпт
Section titled “Крок 2: Запусціць скрыпт”Python-скрыпт (scripts/translate-docs.py) чытае кожны англійскі зыходны файл, адпраўляе яго ў Claude API і запісвае перакладзены markdown:
python3 scripts/translate-docs.py \ --anthropic-key $ANTHROPIC_API_KEY \ --model claude-opus-4-6 \ --workers 5Скрыпту патрабуецца каля 60–70 хвілін, каб перакласці ўсе 28 зыходных файлаў на ўсе 16 мэтавых моў (448 файлаў усяго). Ён выконвае 5 паралельных API-запытаў, каб заставацца ў межах лімітаў хуткасці.
Для адной новай мовы гэта займае каля 4 хвілін.
Крок 3: Зборка
Section titled “Крок 3: Зборка”pnpm buildAstro чытае зыходны markdown, апрацоўвае яго праз шаблоны Starlight і вывадзіць статычны HTML у dist/. Зборка займае каля 30 секунд для ўсіх ~500 старонак.
Крок 4: Разгортванне
Section titled “Крок 4: Разгортванне”pnpm run deployПублікуе сабраны сайт на Cloudflare Workers.
Як працуе скрыпт
Section titled “Як працуе скрыпт”Скрыпт перакладу наўмысна просты — каля 300 радкоў Python. Вось працэс:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐│ Read English │────▶│ Claude API │────▶│ Write target ││ source file │ │ (Opus 4.6) │ │ language file ││ │ │ │ │ ││ getting- │ │ "Translate into │ │ fr/getting- ││ started.md │ │ French..." │ │ started.md │└─────────────────┘ └──────────────────┘ └─────────────────┘ × 5 parallel × 16 languages × 28 filesПромпт дакладна паведамляе Claude, што перакладаць, а што пакідаць без змен:
- Перакладаць: прозу, загалоўкі, подпісы табліц, frontmatter title і description
- Пакідаць на англійскай: блокі коду, інлайн-код, прыклады каманд, шляхі да файлаў, URL, назвы прадуктаў, імёны людзей, ASCII-дыяграмы
Гэтае размежаванне крытычна важнае. Каманда накшталт pnpm build павінна заставацца pnpm build на кожнай мове. Назва прадукту, такая як «En Parlant~» або «Stockfish», не перакладаецца. Але «Getting Started» ператвараецца ў «はじめに» на японскай і «Начало работы» на рускай.
Чаму Opus?
Section titled “Чаму Opus?”Claude Opus 4.6 дае прыкметна лепшыя пераклады, чым хутчэйшыя мадэлі. Розніца відаць у:
- Натуральнасці фармулёвак — Opus піша як носьбіт мовы, а не як перакладчык. Ён перабудоўвае сказы, калі англійскі парадак слоў гучаў бы нязграбна ў мэтавай мове.
- Тэхнічнай дакладнасці — Шахматная тэрміналогія, TTS-жаргон і праграмныя паняцці перакладаюцца з выкарыстаннем правільных даменна-спецыфічных тэрмінаў.
- Паслядоўнасці — Фармальны рэгістр захоўваецца на працягу ўсяго тэксту. Японская ўсюды выкарыстоўвае форму です/ます, не пераключаючыся паміж размоўным і ветлівым стылем пасярод абзаца.
- Апрацоўцы MDX — Opus правільна захоўвае тэгі JSX-кампанентаў (
<Card>,<CardGrid>) і аператарыimportу файлах.mdx, не пашкоджваючы іх.
Розніца ў кошце рэальная — каля $28 за поўны пераклад сайта з Opus супраць $5 з Sonnet — але для 448 файлаў, якія карыстальнікі сапраўды будуць чытаць, якасць таго вартая.
Архітэктура маршрутызацыі лакалей
Section titled “Архітэктура маршрутызацыі лакалей”Гэта тая частка, на якую спатрэбілася найбольш часу.
Праблема
Section titled “Праблема”Starlight вызначае мову старонкі, правяраючы першы сегмент слага змесціва. Калі ён бачыць fr/docs/getting-started, ён разумее, што гэта французская, бо fr — першы сегмент. Але першапачатковая рэалізацыя стварала слагі накшталт docs/fr/getting-started — лакаль была схаваная пад docs/. Starlight бачыў docs як першы сегмент, лічыў усё англійскай і генераваў 7 000+ дублікатаў старонак замест ~500.
Рашэнне
Section titled “Рашэнне”Карыстальніцкая функцыя generateId у src/content.config.ts кіруе тым, як шляхі файлаў ператвараюцца ў слагі змесціва:
generateId({ entry }) { const slug = entry.replace(/\.[^.]+$/, ""); const firstSeg = slug.split("/")[0]; if (firstSeg && localeKeys.includes(firstSeg)) { return `${firstSeg}/docs/${slug.slice(firstSeg.length + 1)}`; } return `docs/${slug}`;}Гэта ставіць моўны прэфікс перад docs/:
| Шлях файла | Слаг | URL |
|---|---|---|
getting-started.md | docs/getting-started | /docs/getting-started/ |
fr/getting-started.md | fr/docs/getting-started | /fr/docs/getting-started/ |
ja/features/puzzles.md | ja/docs/features/puzzles | /ja/docs/features/puzzles/ |
Англійская выкарыстоўвае defaultLocale: "root", што азначае адсутнасць прэфікса — яна жыве непасрэдна на /docs/, а не на /en/docs/.
Масіў localeKeys
Section titled “Масіў localeKeys”Масіў localeKeys у тым жа файле павінен утрымліваць кожную неангельскую лакаль. Калі лакаль ёсць у канфігурацыі Astro, але адсутнічае ў гэтым масіве, яе перакладзены кантэнт лічыцца англійскім — пераключальнік моў ламаецца, а колькасць старонак выбухае.
Кэш сховішча дадзеных
Section titled “Кэш сховішча дадзеных”Astro кэшуе адпаведнасці слагаў у .astro/data-store.json. Пасля любых змен канфігурацыі лакалей гэты файл трэба выдаліць перад перазборкай, інакш зборка пройдзе паспяхова з састарэлай (няправільнай) маршрутызацыяй.
Структура меню
Section titled “Структура меню”Бакавая панэль вызначаецца ў astro.config.mjs. Элементы, якія спасылаюцца на старонку (уласцівасць slug), аўтаматычна выкарыстоўваюць загаловак з frontmatter перакладзенай старонкі — ніякага ручнога перакладу не патрабуецца:
{ slug: "docs/getting-started" }// English: "Getting Started" (from English frontmatter)// French: "Premiers pas" (from French frontmatter)// Japanese: "はじめに" (from Japanese frontmatter)Але подпісы груп і знешнія спасылкі патрабуюць яўных перакладаў:
{ label: "Features", translations: { fr: "Fonctionnalités", es: "Características", de: "Funktionen", ja: "機能", // ... all 16 languages }, items: [ { slug: "docs/features/play-chess" }, { slug: "docs/features/multiplayer" }, // ... ],}Сем элементаў бакавой панэлі патрабуюць ручных перакладаў: Welcome, Features, App Menus, Setup Guides, Under the Hood, Credits і Accessibility. Дадаванне новай мовы азначае дадаванне аднаго запісу ў кожны з гэтых сямі блокаў.
Сувязь з праграмай
Section titled “Сувязь з праграмай”En Parlant~ спасылаецца на гэтую дакументацыю з меню «Даведка». Спасылка ўлічвае лакаль — калі вы карыстаецеся праграмай на французскай, яна адкрывае французскую дакументацыю:
const docsLocalePrefix = useMemo(() => { const lang = i18n.language; // e.g. "fr_FR", "zh_TW" if (!lang || lang.startsWith("en")) return ""; if (lang === "zh_TW") return "/zh-tw"; return `/${lang.slice(0, 2)}`;}, [i18n.language]);Кожная мова, даступная ў праграме, мае адпаведны пераклад на сайце. Адпаведнасць аўтаматычная — fr_FR адлюстроўваецца ў /fr/docs/, ja_JP — у /ja/docs/. Адзіны спецыяльны выпадак — традыцыйная кітайская: zh_TW адлюстроўваецца ў /zh-tw/docs/ (праз дэфіс).
Чаму цяпер гэта проста
Section titled “Чаму цяпер гэта проста”Складаныя часткі ўжо зроблены:
-
Архітэктура маршрутызацыі вырашана. Функцыя
generateId, масіўlocaleKeysі канфігурацыяdefaultLocale: "root"працуюць разам, каб Starlight генераваў правільную URL-структуру. Гэта была найбольшая праблема — спатрэбілася прасачыць больш за 6 зыходных файлаў у Starlight і Astro, каб знайсці і выправіць. -
Скрыпт перакладу апрацоўвае ўсё. Поўны перапераклад сайта, дадаванне адной мовы, абнаўленне асобных файлаў — усё робіцца адным скрыптам з рознымі сцягамі. Ён паўтарае спробы пры перавышэнні лімітаў, размяркоўвае задачы паміж воркерамі і выразна паведамляе пра памылкі.
-
Дадаванне новай мовы — гэта чатыры правкі ў канфігурацыі і адна каманда. Дадайце лакаль у
astro.config.mjs,content.config.tsіtranslate-docs.py, дадайце пераклады бакавой панэлі, запусціце скрыпт. Каля 10 хвілін працы плюс 4 хвіліны перакладу. -
Абнаўленне кантэнту яшчэ прасцей. Адрэдагуйце англійскую крыніцу, запусціце скрыпт з
--filesі--overwriteтолькі для змененых файлаў, перазбярыце. Альбо для дробных тэкставых выпраўленняў рэдагуйце перакладзеныя файлы напрамую. -
Увесь канвеер захаваны як навык. Запуск
/translate_docsправядзе вас праз увесь працэс — які рэжым выкарыстоўваць, якія сцягі перадаць, папярэднія праверкі, верыфікацыя пасля перакладу. Ніякіх інстытуцыйных ведаў не патрабуецца.
Поўны пераклад 448 файлаў на 16 моў каштаваў каля $28 і заняў каля 70 хвілін. Адна новая мова каштуе каля $1,70. Адзін файл, перакладзены на ўсе мовы, каштуе каля $1. Гэта бягучыя выдаткі на падтрыманне дакументацыі актуальнай на 17 мовах.