返回

翻译 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' }。 为了支持 i18n 再加上 gt() 函数,大概也只是顺着现有代码结构自然扩展了一步。

但我每次看到这种写法,都会生理性地感到一阵难受。这完全不是这个库原本的设计用法。 为什么说这是个错误?有两个原因,尤其是在使用机器翻译时:(1) 上下文,以及 (2) 灵活性。

上下文

含义不仅存在于词语本身,也体现在词语的呈现方式上。 比如,单词 "back" 如果出现在返回箭头上,含义很可能和出现在脊椎按摩师简历上的 "back" 完全不同。 此外,如果缺少更大的上下文,译者 (即使是人工译者) 也可能难以正确翻译这个词。 有一个著名的例子:WhatsApp 的 i18n 团队曾把图片编辑工具里的 "crop",在德语中误译成农业语境里的 "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 /> 组件 文档。