Перевод JSX — как использовать условные операторы
Введение
Одна из самых распространённых ошибок в интернационализации, с которыми я сталкиваюсь, — это привычка разбивать простые тернарные выражения на несколько вызовов перевода. Обычно это выглядит примерно так:
const gt = useGT()
return (
<>
<span>
<T> Dark Mode: </T>
</span>
<Button>{enabled ? gt('On') : gt('Off')}</Button>
</>
)По большей части это работает как задумано. До внедрения i18n код, вероятно, выглядел примерно так: { enabled ? 'On' : 'Off' }.
Добавление функции gt() для i18n, скорее всего, было просто естественным продолжением существующей структуры кода.
Каждый раз, когда я это вижу, я невольно морщусь. Библиотека вообще не задумывалась для такого использования. Это ошибка по двум причинам, особенно в контексте машинного перевода: (1) Контекст и (2) Гибкость.
Контекст
Смысл заключается не только в самих словах, но и в том, как они представлены. Слово "back", если оно стоит на стрелке «назад», скорее всего означает совсем не то же самое, что слово "back" в резюме мануального терапевта. Кроме того, без более широкого контекста переводчикам (даже людям) может быть трудно правильно перевести это слово. Есть известная история о том, как отдел i18n в WhatsApp перевёл слово "crop" в инструменте редактирования изображений в сельскохозяйственном смысле на немецкий язык.
Чтобы решить эту проблему контекста, мы можем передавать информацию о том, как представлен контент, с помощью компонентов <T> и <Branch>.
В нашем примере это дало бы нашему "переводчику" более полное понимание того, что означают "on" и "off".
<T>
<span>Dark Mode:</span>
<Button>
<Branch branch={enabled.toString()} true="On" false="Off" />
</Button>
</T>Гибкость
Помимо контекста, ещё один удобный способ использовать перевод с помощью LLM — задействовать их понимание кода. Давайте рассмотрим пример, в котором порядок компонентов может меняться в зависимости от языка:
<T>
I eat lunch at <Branch branch={atHome.toString()} true="home" false="work" />.
</T>Итак, у нас есть два возможных предложения:
- "Я обедаю дома"
- "Я обедаю на работе"
На китайском (мандаринском) это будет:
- "我在家吃午餐"
- "我在公司吃午餐"
Компонент <T> распознаёт, что здесь нужно изменить порядок слов в предложении, и соответствующим образом переставляет свои дочерние элементы —
то, что сложно сделать при переводе строк с помощью тернарных операторов.
<T>
我在
<Branch branch={atHome.toString()} true="家" false="公司" />
吃午餐。
</T>Заключение
Если из этой статьи вы вынесете только одну мысль, то вот она: в коде всегда стоит искать способы использовать контекст и гибкость.
Использование компонента <Branch /> — пожалуй, один из самых простых способов это сделать.
Подробности см. в документации по компоненту <Branch />.