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

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

问题描述

这个 StackOverflow问题让我深思了什么是Rails i18n文件的良好结构,所以我想我为您的考虑/批评,您将分享用于重构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 文件:

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

我可以看到存在大量重复,并且"Email"和"Password"之类的词的上下文是明确的,并且在各自的观点中具有相同的含义.如果我决定将"Email"更改为"e-mail",则必须全部更改它们会有些烦人,因此我想重构字符串以引用某种字典.因此,如何使用一些像这样的&锚点将字典哈希添加到文件的顶部:

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中的锚点引用是否还有其他问题,或者可能只是整个字典"概念存在其他问题?或者只是完全删除默认后端,然后将其替换为 Redis 或如果您有其他需求,则更好Rails默认的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 :出于任何原因,任何人都需要更改翻译,在这种情况下,需要进行市场营销.我将继续从Point 2 Option 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(如果出于某种原因行销公司坚持,则称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?

再次感谢提倡我把所有这些都搞清楚了.

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

推荐答案

TLDNR;不要修改您的文件格式,改进Rails助手并帮助建立标准化的密钥结构!

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

TLDR;

不想下雨游行,但是我对这种技术有一些疑问.在何处使用点快捷方式以及rails助手的键结构如何不同,这可能会让人有些困惑.

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.

毫无疑问,随着应用的增长或添加其他语言,您会发现人物"的名称"属性必须不同于图书"的名称"属性,在英语中我们将其称为标题" -好的,这个例子确实很复杂;),但是当您混合使用越来越多的语言时,这种情况确实经常发生,理想情况下,我们需要一种通用的处理方式.

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天全站免登陆