返回

gt-next@6.6.0

Ernest McCarter avatarErnest McCarter
gt-next6.6.0词典翻译翻译

概览

gt-next 6.6.0 中,我们为对既有(“brown field”)应用进行国际化提供了一种全新的思路。我们引入了 t.obj() 函数,它可以返回已翻译的字典结构。


设计动机

“brownfield”和“greenfield”是从房地产开发领域借用来的术语。greenfield 指的是没有现有建筑物的地块,而 brownfield 则是已有建筑物的地块。在 i18n 语境中,它们分别对应于没有 i18n 基础设施的应用(greenfield)和已经具备 i18n 基础设施的应用(brownfield)。

到目前为止,我们的库一直高度专注于为“greenfield”应用提供国际化支持。比如 <T> 组件或 useGT() hook 就是这样的例子。

我们专门为“brownfield”应用构建的唯一基础设施,是 const t = useTranslations()const t = getTranslations() 这两个 hook,它们参考了 next-intl 的 dictionary 模式。不过,我们的 t() 函数一直存在局限:它只能返回字符串,而不能返回字典的子树。

我们发现,开发者往往希望他们使用的 i18n 库能够返回字典子树,而不仅仅是字符串。因此,当开发者从其他 i18n 库迁移时,gt-next 必须支持这一能力。


用法

来看下面这个字典结构,其中包含你想要遍历的一组条目:

{
  "cards": [
    {
      "title": "卡片1",
      "description": "卡片1 description"
    },
    {
      "title": "卡片2",
      "description": "卡片2 description"
    },
    {
      "title": "卡片3",
      "description": "卡片3 description"
    }
  ]
}

在之前的实现中,你需要根据每个条目的精确键名来逐个访问它们:

import { useTranslations } from 'gt-next'

export default function Page() {
  const t = useTranslations()

  return (
    <>
      <div>
        {t('cards.0.title')}
        {t('cards.0.description')}
      </div>
      <div>
        {t('cards.1.title')}
        {t('cards.1.description')}
      </div>
      <div>
        {t('cards.2.title')}
        {t('cards.2.description')}
      </div>
    </>
  )
}

这种方式显然既不具备可扩展性,也不具备可维护性。

新的 t.obj() 函数提供了一种强大的方式,可以将字典结构作为子树来访问:

import { useTranslations } from 'gt-next'

export default function Page() {
  const t = useTranslations()

  return (
    <>
      <div>
        {t.obj('cards').map((card) => (
          <div key={card.title}>
            {card.title}
            {card.description}
          </div>
        ))}
      </div>
    </>
  )
}

结论

t.obj() 函数是在让 gt-next 更好适配全新项目和存量项目方面迈出的重要一步。通过让开发者可以直接操作字典子树,我们消除了对现有应用进行国际化时的一个主要痛点。

这一增强功能让 gt-next 更接近团队对现代 i18n 库所期望的开发体验,使遍历已翻译内容、更轻松地构建更动态、更易维护的国际化应用成为可能。