Назад

Перевод JSX — как использовать условные операторы

Ernest McCarter avatarErnest McCarter
gt-nextBranchternaryconditionaltranslationi18nTranslate Jsx

Введение

Одна из самых распространённых ошибок, которые я встречаю в интернационализации, — стремление разбивать простые тернарные выражения на несколько вызовов перевода. Часто это выглядит примерно так:

const gt = useGT()

return (
  <>
    <span>
      <T> Тёмная тема: </T>
    </span>
    <Button>{enabled ? gt('Вкл.') : gt('Выкл.')}</Button>
  </>
)

По большей части это работает как задумано. До внедрения i18n код, вероятно, выглядел примерно так: { enabled ? 'On' : 'Off' }. Добавление функции gt() для i18n, скорее всего, было просто естественным развитием существующей структуры кода.

Каждый раз, когда я это вижу, я физически вздрагиваю. Библиотеку вообще не так предполагалось использовать. Есть два аргумента в пользу того, что это ошибка, особенно в контексте использования машинного перевода: (1) Контекст и (2) Гибкость.

Контекст

Смысл заложен не только в самих словах, но и в том, как эти слова представлены. Слово "back", если оно находится на кнопке со стрелкой «назад», скорее всего означает совсем не то же самое, что слово "back" в резюме хиропрактика. Кроме того, без более широкого контекста переводчикам (даже людям) может быть трудно правильно перевести слово. Ходит известная история о том, как i18n‑отдел WhatsApp перевёл слово "crop" в инструменте редактирования изображений как "crop" в значении «сельскохозяйственная культура» на немецком.

Чтобы обойти эту проблему с контекстом, мы можем передавать информацию о представлении контента с помощью компонентов <T> и <Branch>. В нашем примере это даст нашему "переводчику" более полное представление о том, что означают "on" и "off".

<T>
  <span>Темная тема:</span>
  <Button>
    <Branch branch={enabled.toString()} true="Вкл" false="Выкл" />
  </Button>
</T>

Гибкость

Помимо контекста, ещё один удобный способ использовать LLM‑перевод — опираться на его понимание кода. Рассмотрим пример, где порядок компонентов может меняться в зависимости от языка:

<T>
  Я обедаю <Branch branch={atHome.toString()} true="дома" false="на работе" />.
</T>

Итак, у нас есть два возможных предложения:

  • "I eat lunch at home"
  • "I eat lunch at work"

На китайском (мандаринском) это будет:

  • "我在家吃午餐"
  • "我在公司吃午餐"

Компонент <T> понимает, что здесь нужно изменить порядок слов в предложении, и соответственно переставляет свои дочерние элементы — чего сложно добиться при использовании тернарных операторов со строковым переводом.

<T>
  Я обедаю
  <Branch branch={atHome.toString()} true="дома" false="в офисе" />
  .
</T>

Заключение

Если вынести из этой статьи что‑то одно, то это то, что вам всегда стоит искать способы использовать контекст и гибкость в своем коде. Использование компонента <Branch /> — один из самых простых способов сделать это.

Ознакомьтесь с документацией по компоненту <Branch />, чтобы узнать больше.