| 1 | # ADR 0033: Интернационализация (i18n) — ресурсы .NET, Avalonia, ортогонально TOML |
| 2 | |
| 3 | **Статус:** Proposed (направление зафиксировано; объём языков и миграция строк — по плану). |
| 4 | **Дата:** 2026-04-11 |
| 5 | |
| 6 | ## Связанные ADR |
| 7 | |
| 8 | | ADR | Роль | |
| 9 | |-----|------| |
| 10 | | [0028](0028-user-settings-toml-localappdata-and-secrets.md) | пользовательский `settings.toml` | |
| 11 | | [0029](0029-configuration-toml-canonical-ui-facade.md) | канон конфигурации vs UI | |
| 12 | | [0032](0032-hud-banner-configuration-and-grammar.md) | HUD: шаблоны и ключи — не замена i18n | |
| 13 | | [0027](0027-small-team-focus-vs-public-maturity.md) | документация и discoverability | |
| 14 | |
| 15 | --- |
| 16 | ## Контекст |
| 17 | |
| 18 | Текст интерфейса и сообщений сейчас в основном **захардкожен** в коде (в т.ч. русские строки). Для **нескольких языков**, смены языка в рантайме и нормального переводческого контура нужны **устойчивые правила**, а не дублирование длинных фраз в **`settings.toml`** или только в VM. |
| 19 | |
| 20 | Путаница, которую нужно снять заранее: |
| 21 | |
| 22 | - **Конфигурация** ([0028](0028-user-settings-toml-localappdata-and-secrets.md), [0029](0029-configuration-toml-canonical-ui-facade.md)) — канонические ключи, числа, флаги; язык UI — **настройка**, но **не** хранилище всех переведённых строк продукта. |
| 23 | - **HUD и шаблоны** ([0032](0032-hud-banner-configuration-and-grammar.md)) — семантика «что показывать» может жить в TOML; **формулировки для пользователя** по умолчанию должны приходить из **слоя локализации**, а не из необязательной простыни в конфиге. |
| 24 | |
| 25 | ## Решение (намерение) |
| 26 | |
| 27 | <a id="adr0033-p1"></a> |
| 28 | |
| 29 | 1. **Базовый стек:** **.NET embedded resources (`.resx`)** и согласованная с документацией Avalonia схема: ресурсы как источник строк для XAML и кода, установка **`Culture`** / `CurrentUICulture` при старте и при смене языка пользователем; генератор к ресурсам (например `PublicResXFileCodeGenerator`) — по соглашению репозитория, чтобы ключи были доступны из разметки и тестов. |
| 30 | |
| 31 | <a id="adr0033-p2"></a> |
| 32 | |
| 33 | 2. **Разделение ролей:** |
| 34 | - **Переводимые строки UI** — в **ресурсах** (по культурам: `Resources.resx`, `Resources.ru.resx`, …). Каталог ключей стабилен для переводчиков и CI. |
| 35 | - **`settings.toml`** — **не** основной файл перевода всего интерфейса; допустимы **ключи выбора** (например предпочитаемая культура), опциональные **переопределения** отдельных текстов power-user’ом — только если явно спроектировано и не ломает единый каталог переводов (см. [п. 4](#adr0033-p4)). |
| 36 | |
| 37 | <a id="adr0033-p3"></a> |
| 38 | |
| 39 | 3. **Код и MVVM:** строки, которые формируются в **ViewModel** / сервисах, получать через **тот же слой ресурсов** или абстракцию в духе **`IStringLocalizer<T>`** / обёртки над `ResourceManager` — чтобы не размножать литералы и облегчить тесты (подмена культуры в тестах). |
| 40 | |
| 41 | <a id="adr0033-p4"></a> |
| 42 | |
| 43 | 4. **Множественное число, падежи, пол:** не кодировать «русские правила» вручную в каждой VM. Предпочтительно **отдельные ключи ресурсов** для вариантов (`*_one`, `*_few`, `*_many` / языкозависимая схема) или **проверенная библиотека** с правилами CLDR/ICU — выбор на этапе реализации первого неанглийского языка с нетривиальными plural rules; до этого достаточно простых ключей. |
| 44 | |
| 45 | <a id="adr0033-p5"></a> |
| 46 | |
| 47 | 5. **Границы:** этот ADR **не** требует немедленной миграции всех существующих строк; **не** заменяет ADR про конфигурацию; **не** описывает продуктовый User Guide ([0027](0027-small-team-focus-vs-public-maturity.md)) — только **встроенный UI** приложения. |
| 48 | |
| 49 | ## Последствия |
| 50 | |
| 51 | - Появление структуры `*.resx`, политики имён ключей, возможного шага CI «нет пропавших ключей». |
| 52 | - Смена языка в рантайме потребует обновления привязок/уведомлений VM там, где текст не из `{x:Static}`. |
| 53 | |
| 54 | ## Отклонённые / отложенные альтернативы |
| 55 | |
| 56 | - **Все строки только в TOML** — плохо для перевода, дубли, риск правок «в конфиге» вместо каталога; противоречит духу [0029](0029-configuration-toml-canonical-ui-facade.md) как «настройки», а не полный словарь продукта. |
| 57 | - **Только сторонний формат (gettext, Fluent)** без оценки — отложено; переход возможен, если ResX перестанет устраивать команду или инструменты перевода. |
| 58 | |
| 59 | ## Открытые вопросы |
| 60 | |
| 61 | - Список **целевых языков** v1 и порядок (сначала инфраструктура + английский, затем русский и др.). |
| 62 | - Единый **префикс ключей** или разбиение по сборкам/фичам (`Features/*`). |
| 63 | - Интеграция с **палитрой команд** и XML-доками [0018](0018-ide-commands-canonical-xml-documentation.md) — как не разъехаться в языках подсказок. |
| 64 | |