Хорошая практика

Для ВЕБ

Использование шаблонов Markdown улучшает читаемость и упрощает обслуживание как для переводчика, так и для ваших скриптов веб-сайта, которые будут извлекать контент.
Для именованных якорей на многоязычном сайте интересный подход заключается в том, чтобы «жестко кодировать» ссылки с помощью дизайна Markdown.
Напр.: для тега <h2/> с якорем

label-in-current-language

LLM более эффективны, чем люди, в защите ссылок, и LSDE позволяет вам обнаруживать проблемы между различными языковыми версиями.
Таким образом, вы можете делиться ссылкой, которая будет работать на всех языках, и использовать LSDE для управления заменой устаревшего якоря.


Двусмысленность кода

Избегайте двусмысленности при работе с моделями, ориентированными на данные.
Пример:
Плохая практика: Термин 'key' не является явным и затрудняет его поиск.

ts
const PRODUCTS: Product[] = [
	{
		id: 'fcf7o',
		logo: '/icons/fcf7o-icon-40.webp',
		label: 'FCF7O',
		key: 'game:fcf7o.words.game_title',
	},
	{
		id: 'lsde',
		logo: '/icons/lsde-icon-40.webp',
		label: '<c1>LSDE</c1>',
		key: 'software:lsde.name',
	},
	{
		id: 'lsge',
		logo: '/icons/lsge.webp',
		label: 'LSGE',
		key: 'software:lsge.name',
	},
];


Хорошая практика: Примите единую и последовательную конвенцию.
Термин i18nKey очень явный и позволяет точно искать это значение с помощью регулярных выражений (Regex).
ts
const PRODUCTS: Product[] = [
	{
		id: 'fcf7o',
		logo: '/icons/fcf7o-icon-40.webp',
		label: 'FCF7O',
		i18nKey: 'game:fcf7o.words.game_title',
	},
	{
		id: 'lsde',
		logo: '/icons/lsde-icon-40.webp',
		label: '<c1>LSDE</c1>',
		i18nKey: 'software:lsde.name',
	},
	{
		id: 'lsge',
		logo: '/icons/lsge.webp',
		label: 'LSGE',
		i18nKey: 'software:lsge.name',
	},
];




Лень

Плохие идеи рождаются от лени.

Не пытайтесь экономить ключи, выполняя операции по извлечению контента.
Пример:
javascript
const [title, subtitle] = t( 'game:game.title' ).split( /[::]/ );

Это ложная хорошая идея, потому что в некоторых языках символы могут различаться, а порядок слов может меняться.



Формат тегов

Максимально сократите код, предназначенный для дизайна, непосредственно в тексте, чтобы управлять им из кодовой базы.
Например, вы можете указать местоположение изображения, но не его стиль или способ отображения.
Если вам нужно внести изменения в дизайн, вы не захотите быть вынужденными переводить текст на 10 языков только для того, чтобы изменить стиль тега!

Теги могут включать идентификатор, но добавление дополнительной информации обычно крайне не рекомендуется и является плохой практикой.
Пример: Не делайте
<img src='url' left />
а лучше
<img id=1 />
Затем вы получите ID тега изображения, чтобы применить к нему необходимые стили в кодовой базе.
ID должны использоваться буквально, а не через их индекс.
Действительно, в разных языках теги могут быть перемещены и перестать соответствовать исходному индексу.
Использование естественных индексов также усложняет работу для разработчика; попытка угадать, какому индексу соответствует изображение или тег, является настоящей головоломкой.
Поэтому используйте теги с идентификатором, когда вы хотите иметь возможность настраивать их после интерполяции.



CSS

Для перевода сайта, когда у вас есть абзацы, выберите минимальную высоту (`min-height`) после перевода, чтобы избежать визуальных смещений при смене языка.
Напр.: mih={'3lh'}
Это позволяет вам определить минимальную высоту на основе языка, который занимает больше всего строк, тем самым обеспечивая согласованный и ненавязчивый пользовательский опыт (UX).

Пространство имен


Всегда включайте 'namespace' в свои ключи перевода, даже если у вас только одно.
Это значительно упрощает настройку шаблона Regex для поиска ваших ключей.
Напр.: game:a.b.c, common:a.b.c

Управление версиями GIT

Проекты .lsde представляют собой файлы в формате JSON, что упрощает их версионирование с помощью таких инструментов, как Git.
Настоятельно рекомендуется сохранять ваш проект в Git-репозитории, чтобы иметь полную историю изменений и повышенную безопасность.
Хотя в LSDE встроена собственная система резервного копирования, использование Git остается оптимальным решением для управления вашими файлами данных.

Контекст и редактирование

Предоставляйте четкий контекст для каждого ключа
Явный контекст может содержаться в названии ключа, его пути (иерархии), окружении (родительские/дочерние ключи) или метаданных.
Избегайте двусмысленных ключей, которые оставляют место для догадок. Если для понимания назначения ключа требуется проверять его использование в коде, значит, архитектуру ваших данных необходимо улучшить.

Примеры понятных ключей:
game:.scenes.001.events.001.1
game:.scenes.001.events.001.2
game:.scenes.the-ice-land.events.the-lost-house.1
game:.scenes.the-ice-land.events.the-lost-house.2
game:.ui.menus.new-game.label
game:.ui.menus.new-game.description

Эти ключи позволяют сразу понять, что они указывают на диалоги или элементы интерфейса.
Первые два используют числовые идентификаторы (IDs): эффективный подход для экшн-игр, где художественное направление (DA) гибко и может меняться, не влияя на техническую структуру.
Следующие два используют семантические идентификаторы: они незаменимы для нарративных игр, где контент тесно связан с кодом. Это позволяет избежать нарушения связи между повествованием и логикой игры.
Последние два четко описывают элементы меню (название и описание).

Примеры плохой практики:
game:events.001.1 (Слишком расплывчато: где используется это событие?)
game:.scenes-events-the-lost-house.1 (Избыточность в пути)
game:.ui-menus.new-game-label (Ненужная конкатенация)

Избегайте избыточности в путях. Если вам нужно облегчить поиск, лучше экспортируйте файл типов, содержащий объединенные ключи, вместо того чтобы портить структуру ваших данных JSON.

Избегайте зависимости от неявного контекста
Строка никогда не должна зависеть от внешних элементов для понимания (положение на экране, цвет, иконка).
Пример: избегайте
"Нажмите здесь, чтобы продолжить"
Предпочтительнее
"Перейти к оплате"
Текст должен оставаться понятным даже в отрыве от пользовательского интерфейса (UI).
В некоторых языках может не быть прямого перевода или могут потребоваться разные формулировки в зависимости от действия и расположения текста.
Тексты кнопок действий должны описывать действие и объект: «Перейти к оплате», «Скачать отчет PDF», а не «Нажмите здесь» или «Узнать больше» без уточнений.

Избегайте сегментированных фраз и избыточной модульности
Не переносите принципы программирования (такие как S.O.L.I.D.) на написание контента i18n. Написание текстов и кодинг — это разные дисциплины.
Отдавайте предпочтение полным предложениям, а не фрагментам, так как каждый язык имеет свой собственный синтаксис.
Хотя такие фреймворки, как `i18next`, поддерживают вложенность («nesting»), это часто создает ненужную сложность. Если требуется вариация, перепишите фразу полностью. Ограничьте интерполяцию простыми переменными, такими как имена или числа.

Указывайте ограничения отображения (UI)
Если интерфейс накладывает лимит символов или ограничение по длине, укажите это в метаданных и предоставьте визуальный пример (скриншот или макет).
Переводчику проще адаптировать свой текст под ограниченный интерфейс, чем программисту делать UI динамическим для всех языков мира. Делегирование этой задачи автору текста гарантирует лучший пользовательский опыт (UX).

Запрет на неконтролируемые эмодзи
Не вставляйте специальные символы или эмодзи напрямую в текст.
Используйте переменные (например: <t title=), чтобы контролировать их отображение через код. Отображение эмодзи значительно варьируется в зависимости от операционной системы и окружения пользователя.

Избегайте культурных метафор
Идиоматические выражения, игру слов и локальные метафоры следует исключить из общих строк.
То, что понятно на одном языке, может стать абсурдным или непереводимым на другом.

Исходите из того, что переводчик не видит приложение
Пишите так, как будто у переводчика нет доступа ни к коду, ни к UI.
Все необходимое для понимания должно присутствовать в самом ключе, его иерархии или метаданных.

Технические аспекты I18n


Именованные и явные плейсхолдеры
Отдавайте предпочтение именованным плейсхолдерам (`{username}`, `{count}`), а не позиционным индексам (`{0}`, `{1}`). LSDE предлагает специальный раздел для переменных, чтобы определить их контекст и обеспечить их отслеживаемость в рамках вашего проекта.

Один плейсхолдер на концепт
Каждый плейсхолдер должен быть атомарным и представлять одну единицу данных (имя, дата, число). Избегайте использования универсальных или полиморфных переменных, которые усложняют перевод и интерпретацию.

Совместимость с RTL (Right-to-Left)
Заранее учитывайте отображение для языков, пишущихся справа налево. Рендеринг должен оставаться плавным и структурно правильным без необходимости ручного изменения строки символов.

Запрет конкатенации
Никогда не составляйте предложение, комбинируя несколько ключей перевода. Чтобы соблюсти синтаксис и грамматические согласования, характерные для каждого языка, каждое полное предложение должно соответствовать уникальному ключу.