使用字典重构 Ruby on Rails i18n YAML 文件 [英] Refactoring Ruby on Rails i18n YAML files using dictionaries

查看:19
本文介绍了使用字典重构 Ruby on Rails i18n YAML 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个 StackOverflow 问题让我思考了什么是 Rails i18n 文件的良好结构,所以我想我'd 共享另一种结构来重构 Rails i18n yml 文件供您考虑/批评.

This StackOverflow question gave me food for thought on what is a good structure for Rails i18n files, so I thought I'd share another structure for refactoring Rails i18n yml files for your consideration/criticism.

因为我愿意

  1. 保留默认的应用程序结构,以便我可以在视图中使用 t('.some_translation') 等速记惰性"查找,并了解应用程序中使用翻译的位置,
  2. 尽可能避免重复字符串,尤其是单词不仅相同,而且具有相同的上下文/含义,
  3. 只需更改一次密钥,即可在所引用的任何地方反映出来,
  1. keep the default app structure so I can use shorthand "lazy" lookups like t('.some_translation') in my views, as well as have an idea where translations are used in the app,
  2. avoid as much string repetition as possible, in particular with words that are not just the same, but also have identical contexts/meanings,
  3. only have to change a key once to have it reflected everywhere it's referenced,

对于一个看起来像这样的 config/locales/en.yml 文件:

for a config/locales/en.yml file that looks something like this:

activerecord:
  attributes:
    user:
      email: Email
      name: Name
      password: Password
      password_confirmation: Confirmation
  models:
    user: User
users:
  fields:
    email: Email
    name: Name
    password: Password
    confirmation: Confirmation
sessions:
  new:
    email: Email
    password: Password

我可以看到存在大量重复,并且电子邮件"和密码"等词的上下文是明确的,并且在各自的视图中具有相同的含义.如果我决定将电子邮件"更改为电子邮件",则必须全部更改它们会有点烦人,所以我想重构字符串以引用某种字典.那么,如何使用一些 & 锚在文件顶部添加字典哈希,如下所示:

I can see that there is significant repetition, and that the context of words like "Email" and "Password" are unambiguous and have the same meaning in their respective views. It would be a bit annoying to have to go and change them all if I decide to change "Email" to "e-mail", so I'd like to refactor the strings to reference a dictionary of some sort. So, how about adding a dictionary hash to the top of the file with some & anchors like this:

dictionary:
  email: &email Email
  name: &name Name
  password: &password Password
  confirmation: &confirmation Confirmation

activerecord:
  attributes:
    user:
      email: *email
      name: *name
      password: *password
      password_confirmation: *confirmation
  models:
    user: User
users:
  fields:  
    email: *email
    name: *name
    password: *password
    confirmation: *confirmation
sessions:
  new:
    email: *email
    password: *password

您仍然可以继续使用静态字符串(例如上面的用户"),但是当您在视图中获得多个完全相同的单词/短语的实例时,您可以将其重构到字典中.如果基础语言中的键的字典翻译对目标语言没有意义,那么只需将目标语言中的引用值更改为静态字符串或将其作为额外条目添加到目标语言的字典中.我敢肯定,如果每种语言的字典变得太大且笨拙,可以将它们重构到另一个文件中(只要它在翻译文件的顶部重新导入,以便参考工作).

You could still continue to use static strings (eg "User" above), but whenever you get more than one instance of exactly the same word/phrase in your views, you could refactor it out to the dictionary. If the dictionary translation of a key in the base language doesn't make sense for a target language, then just change out the referenced value in the target language to a static string or add it as an extra entry to the target language's dictionary. I'm sure each language's dictionary could be refactored out into another file if they get too big and unwieldy (as long as it then gets reimported at the top of the translation file so the references work).

这种构建 i18n yaml 文件的方式似乎适用于我尝试过的一些本地测试应用程序.我希望美妙的 Localeapp 将在未来为这种锚定/引用提供支持.但是无论如何,所有这些字典讨论都不可能是一个原创的想法,那么 YAML 中的锚引用是否还有其他问题,或者可能只是整个字典"概念?或者,如果您有 Rails 之外的需求,是否最好完全删除默认后端并将其替换为 Redis 或其他东西默认 i18n 约定?

This way of structuring i18n yaml files seems to work well with some local test apps I tried it on. I'm hoping the wonderful Localeapp will provide support for this kind of anchoring/referencing in the future. But anyway, all this dictionary talk can't possibly be an original idea, so are there other issues with anchor referencing in YAML, or maybe just with the whole "dictionary" concept in general? Or is it just better to just rip out the default backend entirely and replace it with Redis or something if you have needs beyond Rails default i18n conventions?

编辑:

我想尝试解决在下面的评论中提到的 tigrish 的工作流程示例,而不是作为他答案下方的另一条评论.如果我似乎没有得到所要表达的观点或者我只是天真,请原谅:

I wanted to try and address tigrish's workflow example mentioned in a comment below up here, rather than as another comment below his answer. Please excuse me if I don't seem to be getting the points being made or if I'm just naive:

第 1 点:ActiveRecord 模型有一个通用的名称"属性,它们都只是指向名称的通用字典:

Point 1: you have a general "name" attribute for ActiveRecord models, and they all just point to the generic dictionary for name:

dictionary:
  name: &name Name

activerecord:
  attributes:
    name: *name
    user:
      name: *name
    product:
      name: *name

第 2 点:只需更改用户模型的名称.其他名称保持不变.

Point 2: Name for User model only needs to be changed. Other names stay the same.

选项 1:在后端保持模型字段名称相同,只需更改它指向的前端翻译.

Option 1: Keep the model field names the same on the backend and just change the front end translation it points to.

dictionary:
  name: &name Name
  full_name: &full_name Full Name

activerecord:
  attributes:
    name: *name
    user:
      name: *full_name
    product:
      name: *name

选项 2:同时更改用户模型字段名称.这将需要更改代码中对该键的任何引用,以及 change_table/rename_column 迁移.

Option 2: Change the User model field name as well. This would require changing any references to this key in the code, and a change_table/rename_column migration.

dictionary:
  name: &name Name
  full_name: &full_name Full Name

activerecord:
  attributes:
    name: *name
    user:
      full_name: *full_name
    product:
      name: *name

选项 3:如果您想非常彻底,请将名称"中包含的信息重构为单独的数据库/Activemodel 字段,这需要新的字典条目和迁移.您可以根据自己的观点决定如何显示全名":

Option 3: If you want to be very thorough, refactor the information contained in a "name" out in to separate database/Activemodel fields, which would need new dictionary entries and a migration. You can decide on your views how you would want a "full name" to display:

dictionary:
  name: &name Name
  name_prefix: &name_prefix Prefix
  first_name: &first_name First
  middle_name: &middle_name Middle
  last_name: &last_name Last
  name_suffix: &name_suffix Suffix

activerecord:
  attributes:
    name: *name
    user:
      name_prefix: *name_prefix
      first_name: *first_name
      middle_name: *middle_name
      last_name: *last_name
      name_suffix: *name_suffix
    product:
      name: *name

第 3 点:任何人出于任何原因都需要更改翻译,在这种情况下是营销.我将从第 2 点选项 1 的示例继续进行

Point 3: Anyone for any reason needs a translation change, Marketing in this case. I'll follow on from Point 2 Option 1's example

选项1:模型字段名称相同,只是改变前端翻译.

Option 1: Model field names same, just change the front end translation.

dictionary:
  name: &name Name
  full_name: &full_name Full Name
  funky_name: &funky_name Ur Phunky Phresh Naym

activerecord:
  attributes:
    name: *name
    user:
      name: *full_name
    product:
      name: *name
sessions: # Sign up page keys
  new:
    name: *funky_name

选项 2:出于某种原因,Funky name"也迫切需要保存到数据库中.如果没有人反对,我们就称它为 username(如果出于某种原因 Marketing 坚持认为,则称它为 funky_name).

Option 2: "Funky name" desperately needs to be saved to the database, too, for some reason. Let's call it a username if no one objects (or funky_name if for some reason Marketing insists).

dictionary:
  name: &name Name
  full_name: &full_name Full Name
  funky_name: &funky_name Ur Phunky Phresh Naym

activerecord:
  attributes:
    name: *name
    user:
      name: *full_name
      username: *funky_name
    product:
      name: *name
sessions: # Sign up page keys
  new:
    name: *name
    funky_name: *funky_name

是的,所以我承认我不知道自己在做什么,但是,我愿意被公开拒绝,以了解为什么这种在 Haml 中使用 i18n 的方式在 Rails 中是一个坏主意应用程序.难以阅读?维护噩梦?如果我使用(我认为是)该语言的一项功能,是否真的被认为是破解文件格式"?

Right, so I admit that I have little idea what I'm doing, however, I'm willing to be shot down publicly in order to understand why this way of working with i18n in Haml is a bad idea in a Rails app. Difficult to read? Maintenance nightmare? Is it really considered 'hacking the file format' if I use (what I think is) a feature of the language?

再次感谢 tigrish 驱使我完成这一切.

Thanks again to tigrish for driving me to get all this out.

推荐答案

TLDNR;不要破解您的文件格式,改进 rails helpers 并帮助建立标准化的密钥结构!

TLDNR; Don't hack your file format, improve the rails helpers and help to establish a standardized key structure!

TLDR;

不想在你的游行中下雨,但我对这种技术有一些问题.在哪里使用点快捷方式以及rails helpers 的键结构有何不同的困境可能有点令人费解.

Don't want to rain on your parade, but I have a few issues with this technique. The dilemma of where to use the dot shortcut and how the rails helpers' key structure differs can be a bit puzzling.

据我了解,问题基本上是关于干燥您的语言环境文件并使用 YAML 语言的功能来实现这一点.

As I understand it, the question is basically about DRYing up your locale files and using a feature of the YAML language to achieve this.

首先,锚点只能真正保证适用于 YAML,因此该解决方案不能普遍应用于 I18n.如果您使用不同的后端,此技术可能不可行.无论是 SQL、Redis 还是 Json,我都不知道它们中的任何一个具有任何类型的符号链接功能.这并没有过多地考虑在引擎盖下,翻译实际上是重复的.

Firstly, anchors are only really guaranteed to work for YAML so this solution can't be applied generically to I18n. This technique is probably not feasible if you use a different backend. Be it SQL, Redis or Json, I'm not aware of any of them having any kind symlinking functionality. And that's without going too much into the fact that under the hood, the translations are in fact duplicated.

我遇到的第二个也是更大的问题是关于语言学的.您的示例说明所有这些术语在上下文和含义上完全相同.不幸的是,只有在极其简单的示例中才会出现这种情况.

The second and bigger problem that I have is about linguistics. Your example makes the case that all of these terms are exactly equal in context and in meaning. Unfortunately this is only ever the case in extremely simple examples.

毫无疑问,随着应用程序的增长或添加其他语言,您会发现 Person 的name"属性必须不同于 Book 的name"属性,在英语中我们称之为title"- 好吧,这个例子真的很复杂;)但是当你混合越来越多的语言时,这种情况确实经常发生,理想情况下,我们需要一种通用的方式来处理它.

Undoubtedly, as your app grows or as you add additional languages, you'll find that a Person's "name" attribute has to be distinct from say a Book's "name" attribute which in English we'll call a "title" - OK, this example is really convoluted ;) but as you mix in more and more languages this situation does occur frequently and ideally, we want a generic way of dealing with it.

我认为在很大程度上,复杂性来自于使用不同默认值演变而来的 Rails 助手,而没有关键结构的约定.

I think in large part, the complexity comes from the rails helpers that have evolved with different defaults without there being a convention for key structures.

回到您的示例,您提到了我认为非常不同的两件事:使用 rails 助手的 activerecord 属性翻译和使用点快捷方式的查看翻译.

Going back to your example you mention 2 things that I think are really distinct : activerecord attribute translations which use the rails helpers and view translations which use the dot shortcut.

让我举一个非常频繁的工作流程示例:

Let me give you an example of a workflow that is super frequent :

  1. 在这种情况下,您使用用户的名称"字段创建一个表单,您希望使用通用的名称"属性翻译(label_tag 应该使用类似 :'attributes.name' 的内容).这是最简单、最干燥的案例,可让您快速启动并运行,批量转换简单属性.
  2. 稍后您决定只需要将此模型的用户姓名"翻译为全名",因此您创建了一个在 label_tag 的查找调用中具有更高优先级的新翻译(例如:'activerecord.attributes.users.name'))
  3. 后来,营销人员有了一个绝妙的主意,即在此页面上(并且仅在此页面上)将此字段的标签显示为输入您的新名字".我们不再描述 name 属性,我们描述的是这种形式的特定视图;这就是点快捷方式将 :'.form.name' 转换为类似 ':users.new.form.name' 的地方.

我们无法使用共享的字典"来处理这种情况.当然,我们的语言环境文件会是 DRY,但我们的语言/翻译问题与我们在这里的开发人员问题大不相同(遗憾的是).

There is no way we could handle this situation with a shared "dictionary". Sure our locale file would be DRY, but our linguistic/translation concerns are vastly different from our developer concerns here (sadly).

从好的方面来说,我们可以更清楚地了解我们所描述的内容类型,并将其反映在我们的关键结构和工具中 - 对我来说,这就是前进的方向!:)

On the plus side, we can get clearer about what kind of content we're describing and reflect that in our key structures and in our tools - that for me is the way forward! :)

这篇关于使用字典重构 Ruby on Rails i18n YAML 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆