简化Rails应用程序中的翻译
国际化(i18n)或翻译是任何面向全球用户的应用程序的一个组成部分。Rails开箱即支持这一点。
要在你的Rails应用程序中添加一组翻译,是相当容易的。默认情况下,rails会在config/locales 文件夹中提供一个en.yml :
en:
hello: "Hello world"
这提供的是,locale:en 中的键hello 将有值Hello world 。
在这篇文章中,我们将专注于如何在应用程序变大时增加翻译文件,并尽可能避免杂乱和重复。
考虑一个有命名空间的应用程序,以及它下面的一组不同的上下文。在翻译文件中,最终出现下面这样的结构是很常见的:
en:
admin:
attendance
policies:
index:
blank:
title: Some title
我们有一些命名空间要跨越,直到我们到达我们所需要的键,这就是title 。
考虑到目录app/views/admin/attendance/policies ,用于管理下的所有考勤命名空间的视图。它包含几个文件index.html.slim,_table.html.slim 。blank.html.slim
现在,如果对文件blank.html.slim 使用这个标题,我们就会把它当作t('admin.attendance.policies.index.blank.title') 。这不是好事,如果我们的关键词越来越大,或者我们有更多的命名空间,这只会变得更糟。
使用rails的懒人查询
Rails为我们提供了一个懒人查找功能,在这个功能中,如果翻译的路径与视图的路径直接同步,我们就不必提供整个路径。
让我重构一下上面的内容,给你看看。
我更新了视图文件app/views/admin/attendance/policies/_blank.html.slim ,使其翻译为。t(.title)
现在我更新了翻译文件,如下所示(请注意层次结构)
en:
admin:
attendance:
policies:
blank:
title: Some title
这里我去掉了索引,让blank 的键直接在policies 的键下。这就像我们的应用程序中的目录结构一样(检查上面的路径共享)。
如果这个结构匹配,rails会自动拾取t('.title') 。
长链路径是不需要的。
这将需要我们重新安排一下翻译文件,但额外的努力是值得的。
对常用术语进行分组
我们有很多表格和组件使用了与Submit 、Cancel 等相同的词,这些词在很多地方都被使用。我们应该在最小的层次下对它们进行分组,即没有一个长的链条。例如,与形式有关的东西可以被归类为:
en:
form:
submit: Submit
cancel: Cancel
然后作为t('form.submit') 或t(:submit, scope: :form) 参考:你也可以像这样连锁作用域 t(:key, scopes: [:scope_one, :scope_two]),让我们尽可能地坚持最小化。
它可能不是表单,但可以是你可能遇到的应用程序的任何其他实体,最终目的是为了防止这种t('admin.some_module.some_resource.some_action.some_form') == "Submit" ,并且t('admin.another_module.another_resource.another_action.another_form') == "Submit"
注意:我已经看到了human_attribute_name 的用法,它在抽象出复杂性方面也很好--这里没有提到,因为这篇文章的意图主要是关注视图和参数,它们可能不会一直与模型对象打交道,即使有模型对象的也不一定会显示准确的名称。
分割文件
由于我们有很多模块,我们可以去把翻译文件也拆开。考虑到上述情况,任何特定模块的翻译都可以放在以下位置locales/admin/<module_name>/*.yml
目前我们看到的例子中,所有的翻译都在这个位置:config/locales/en.yml 。
按照分割的方法,我们最终会得到这样的路径config/locales/admin/attendance/en.yml
即使以这种方式,Rails也会懒得去查找翻译。
尽管拆分无助于减少冗余,但它有助于更好地安排。
方法
结合这三种方法将是一个理想的方法。首先让懒人查询发挥作用,然后重新安排常用的文件,最后将文件拆分。这没有硬性规定,因为它应该以同样的顺序进行,但最终我们应该能够做到所有这些。
决定一个词是在全局范围内还是在一个命名空间下移动是一个偏好,例如,如果像 "步骤1 "这样的东西在所有模块中都使用,那么它很可能被移出模块。只有步骤的定义可以改变。如果一个词只在两个模块中使用,那么把它放在模块中也是可以的,但翻译的理想用途是不重复任何一个词,也就是说,如果我们需要改变一些东西,我们只能在一个地方改变它。
提示:在做重构的时候,可以看看这个宝石i18n-tasks。它可以帮助你找到并管理丢失和未使用的翻译。