为什么需要 keystone-translated-fields
在开发多语言网站时,我们通常需要将网站的用户界面、邮件内容、数据库模型等进行国际化处理。这个过程中最核心的一项工作就是实现多语言数据管理。
在 node.js 的 Web 应用开发中,KeystoneJS 是一个流行的开源 CMS 和 web 应用框架,它为我们提供了一种构建支持多语言网站的解决方案。但是,KeystoneJS 默认的多语言支持并不够完善,对于一些复杂的多语言场景(例如多语言表单)无法很好地处理。因此,我们需要使用一些第三方的 npm 包来扩展 KeystoneJS 的多语言功能。
其中 keystone-translated-fields 就是一款非常实用的 npm 包,它可以帮助我们快速地实现多语言数据管理。本篇文章将详细介绍 keystone-translated-fields 的使用方法以及注意事项。
keystone-translated-fields 如何工作
keystone-translated-fields 的设计理念是将一个字段的多语言内容存储在一个数组中。例如,如果我们有一个叫做 "title" 的字段,那么它的多语言版本可以被存储在一个数组中,每个元素都是一个对象,代表不同的语言:
{ title: [ { value: "Hello, world!", locale: "en" }, { value: "你好,世界!", locale: "zh" }, { value: "Bonjour le monde!", locale: "fr" } ] }
在数据库中,这个数组将被存储在一个 JSON 字段中,具体的数据库实现方式取决于我们所使用的 ORM 或数据库。例如,使用 MongoDB 时,我们可以将上面的 JSON 对象存储成以下形式:
-- -------------------- ---- ------- - ------ - - ------ ------- -------- ------- ---- -- - ------ --------- ------- ---- -- - ------ -------- -- -------- ------- ---- - -- ---------- ------- -------- ---------- --------- ---------- -------- -- ------- -
其中,title__en、title__zh、title__fr 是 title 字段的英、中、法语言版本。
使用 keystone-translated-fields
安装 keystone-translated-fields
使用 npm 安装:
npm install --save keystone-translated-fields
集成 keystone-translated-fields
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------------------------ - -------------------------------------- --------------- ------- --- ------ ---------- ------------------------------ --------- --------- ----- -------- ----- ---------- ----- ------- ----- ----- ------- ------ --- ----------------------------------------
在上面的代码中,我们首先需要引入 keystone 和 keystone-translated-fields 。然后,在初始化 KeystoneJS 实例之后,调用 keystoneTranslatedFields.init 函数即可。
定义多语言字段
在 KeystoneJS 的模型(model)中定义一个多语言字段,我们只需要添加一个名为 type: Types.TranslatedString
的字段即可。
例如,下面我们定义了一个 User 模型,其中 name 字段是一个多语言字段:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ----- - --------------------- ----- ---- - --- ---------------------- ---------- ----- - ----- ----------------------- --------- ---- - --- ----------------
使用多语言字段
在模板中使用多语言字段时,我们可以直接引用数组的某个元素即可。例如,在 ejs 模板中,我们可以这样使用多语言的 name 字段:
<h1><%= user.name[user.lang].value %></h1>
其中,user.lang 表示当前语言。通过这种方式,我们可以使用一个通用的模板来显示多语言内容。
添加支持的语言
在 keystone 中,我们可以通过 i18n 中间件来自动识别当前语言,并设置到 req.locale 中。然后,我们可以通过 req.locale 来选择当前要使用的 language。
在 keystone-translated-fields 中,默认支持以下 14 种语言:
- en: 英语
- es: 西班牙语
- fr: 法语
- de: 德语
- he: 希伯来语
- it: 意大利语
- ja: 日语
- ko: 韩语
- nl: 荷兰语
- pt: 葡萄牙语
- ru: 俄语
- sv: 瑞典语
- uk: 乌克兰语
- zh: 中文
我们可以通过 keystone.init 的 options.i18n.supportedLocales 设置支持的语言,例如:
keystone.init({ ... i18n: { supportedLocales: ['en', 'zh'] } ... });
在上面的例子中,我们设置了支持英语和中文这两种语言。在添加数据时,默认语言将会是第一个支持的语言(即英语),但用户可以随时在界面上修改默认语言。
完整示例代码
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------------------------ - -------------------------------------- --------------- ------- --- ------ ---------- ------------------------------ --------- --------- ----- -------- ----- ---------- ----- ------- ----- ----- ------- ------- ------- - ----------------- ------ ----- - --- ---------------------------------------- ----- ----- - --------------------- ----- ---- - --- ---------------------- ---------- ----- - ----- ----------------------- --------- ---- -- ------ - ----- ------------ --------- ----- ------- ---- - --- ----------------
注意事项
keystone-translated-fields 目前还不是一个完美的解决方案,使用它也需要注意一些事项:
- 多语言字段在数据库中的存储可能会比较浪费存储空间。
- 目前 keystone-translated-fields 没有提供 Locale Selector 组件的实现,需要我们自己来实现。(后续版本可能会提供该组件)
- keystone-translated-fields 会影响到 KeystoneJS 的默认搜索和排序功能,需要我们自己来实现定制化的搜索和排序。
- keystone-translated-fields 目前还有一些 bug 和性能问题,需要我们进行认真的测试和调试。
总之,keystone-translated-fields 是 KeystoneJS 多语言支持的一个比较好的扩展,但使用时需要我们对其进行仔细的评估和使用。
总结
在本篇文章中,我们详细介绍了 keystone-translated-fields 的设计思路和使用方法,同时也提到了它存在的一些缺点和限制。得益于 keystone-translated-fields 的帮助,我们可以更加轻松地在 KeystoneJS 中实现多语言支持,缩短开发周期,提升开发效率。
在实际项目开发中,我们可以在 keystone-translated-fields 的基础上进一步扩展,并结合 KeystoneJS 的其他功能来构建强大的多语言 web 应用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/600559e481e8991b448d7826