Назад

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

Ernest McCarter avatarErnest McCarter
gt-nextBranchтернарный операторусловные операторыпереводi18nПеревод 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 />.