Ruby-on-rails 你如何在 Rails 中构建 i18n yaml 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10282857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you structure i18n yaml files in Rails?
提问by Mohamad
I started populating an en yaml file in Rails and I can already tell it will get messy and out of hand before too long. Is there a convention to keeping this file organized?
我开始在 Rails 中填充一个 en yaml 文件,我已经知道它会在不久之后变得混乱和失控。是否有保持此文件组织的约定?
So far I have this structure:
到目前为止,我有这个结构:
language:
resource:
pages: # index, show, new, edit
page html elements: # h1, title
activerecord:
attributes:
model:
property:
Now I have the following things that I want to fit into this structure but I'm unsure how to:
现在我有以下东西想要适应这个结构,但我不确定如何:
- Navigation
- Button text (save changes, create account, etc)
- Error messages from controller flash
- How to add multi-word keys. Do I use a space or an underscore? For exmaple,
t(".update button")) ort(".update_button")
- 导航
- 按钮文本(保存更改、创建帐户等)
- 来自控制器闪存的错误消息
- 如何添加多字键。我使用空格还是下划线?例如,
t(".update button")) 或t(".update_button")
Is there a convention to locale file structure?
是否有语言环境文件结构的约定?
回答by tigrish
I've found that the best overall strategy is to somewhat reproduce the file structure so that given any translation, I can immediately find where it was called from. This gives me some kind of context for making the translation.
我发现最好的整体策略是在一定程度上重现文件结构,以便在进行任何翻译时,我可以立即找到它的调用位置。这给了我进行翻译的某种背景。
The majority of application translations are found in views, so my biggest top level namespace is usually views.
大多数应用程序翻译都可以在视图中找到,所以我最大的顶级命名空间通常是views.
I create sub namespaces for the controller name and the action name or partial being used ex :
我为控制器名称和正在使用的操作名称或部分创建子命名空间:
views.users.index.titleviews.articles._sidebar.header
views.users.index.titleviews.articles._sidebar.header
Both of these examples should make it obvious what part of my app we're translating and which file to look in to find it.
这两个示例都应该清楚地表明我们正在翻译我的应用程序的哪个部分以及要查找哪个文件才能找到它。
You mention navigation and buttons, if they are to be generic, then they belong in the views.applicationnamespace just as do their view counterparts :
你提到导航和按钮,如果它们是通用的,那么它们views.application就像它们的视图对应物一样属于命名空间:
views.application._main_nav.links.about_us- a link in our app's main navigation partialviews.application.buttons.saveviews.application.buttons.create- I have a bunch of these buttons ready to be used when needed
views.application._main_nav.links.about_us- 我们应用程序主导航部分中的链接views.application.buttons.saveviews.application.buttons.create- 我有一堆这些按钮可以在需要时使用
Flash messages are generated from the controller, so their top level namespace is... controllers! :)
Flash 消息是从控制器生成的,因此它们的顶级命名空间是... controllers!:)
We apply the same logic as we do to views :
我们应用与视图相同的逻辑:
controllers.users.create.flash.success|alert|notice
controllers.users.create.flash.success|alert|notice
Again if you wanted to provide generic flash messages like "Operation successful", you would write something like this :
同样,如果您想提供诸如“操作成功”之类的通用 Flash 消息,您可以编写如下内容:
controllers.application.create.flash.notice
controllers.application.create.flash.notice
Finally, keys can be anything that is valid YAML, but please stick to using periods .as separators and underscores _between words as a matter of convention.
最后,键可以是任何有效的 YAML,但作为约定,请坚持使用句点.作为分隔符和_单词之间的下划线。
The only thing left to sort out now, is getting rails' translations into its own namespace to clean up our top level :)
现在唯一需要解决的事情就是将 rails 的翻译转换到自己的命名空间中以清理我们的顶层 :)
回答by Paul Fioravanti
I know that an answer has already been accepted, but this question provided me with some food for thought and I thought I'd share another structure for Rails i18n yml files for your consideration/criticism.
我知道一个答案已经被接受,但是这个问题为我提供了一些思考的食物,我想我会分享 Rails i18n yml 文件的另一个结构供您考虑/批评。
Given that I would like to
鉴于我想
- keep the default app structure so I can use shorthand "lazy" lookups like
t('.some_translation')in my views, - avoid as much string repetition as possible, in particular with words that are not just the same, but also have identical contexts/meanings,
- only have to change a key once to have it reflected everywhere it's referenced,
- 保留默认的应用程序结构,这样我就可以
t('.some_translation')在我的视图中使用速记“惰性”查找, - 避免尽可能多的字符串重复,尤其是那些不仅相同而且上下文/含义相同的单词,
- 只需更改一次键即可将其反映到所引用的任何地方,
for a config/locales/en.ymlfile that looks something like this:
对于看起来像这样的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
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
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.
每当您在视图中获得多个完全相同的词/短语实例时,您可以将其重构到字典中。如果基本语言中键的字典翻译对目标语言没有意义,则只需将目标语言中的引用值更改为静态字符串,或将其作为额外条目添加到目标语言字典中。我敢肯定,如果每种语言的字典变得太大而笨拙,都可以将它们重构到另一个文件中。
This way of structuring i18n yaml files seemed to work well with some local test apps I tried it on. I'm hoping the wonderful Localeappwill 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 Redisor something?
这种构建 i18n yaml 文件的方式似乎适用于我尝试过的一些本地测试应用程序。我希望精彩的Localeapp将来会为这种锚定/引用提供支持。但无论如何,所有这些字典谈话不可能是一个原创的想法,那么 YAML 中的锚引用是否还有其他问题,或者可能只是整个“字典”概念?或者完全删除默认后端并用Redis或其他东西替换它会更好吗?
回答by Mohamad
It's almost two years after I asked this question, and I want to share some insights. I believe the optimal structure is to namespace translations according to their MVC role (models, views, controllers). This keeps the locale file tidy, and prevents namespace collisions (for example, the scope en.userscan represent a view or a controller).
我问这个问题已经快两年了,我想分享一些见解。我相信最佳结构是根据它们的 MVC 角色(模型、视图、控制器)进行命名空间转换。这使区域设置文件保持整洁,并防止命名空间冲突(例如,范围en.users可以表示视图或控制器)。
en:
controllers:
users:
show:
welcome_flash: "Welcome back!"
mailers:
users_mailer:
welcome_email:
subject: "Good of you to join us"
views:
users:
show:
notice: "Oh no!
But using tidy namespaces like that breaks the lazy lookup feature in Rails. If you use lazy lookup, Rails will insert the namespace automatically for you, and it will not include the top level namespaces you created (views, controllers, etc...).
但是使用像这样整洁的命名空间会破坏 Rails 中的惰性查找功能。如果你使用懒惰的查找,Rails会自动插入命名空间的你,也不会包含您所创建的顶级命名空间(views,controllers,等...)。
For example, the scope of t('.welcome_flash')resolves to en.users.show. Which stinks because users isn't clearly defined. What is it? A controller? A view? Something else?
例如,范围t('.welcome_flash')解析为en.users.show。这很糟糕,因为用户没有明确定义。它是什么?控制器?一个看法?还有什么?
To solve this problem I created the gem I18nLazyLookup. It allows you to use lazy lookup with your own custom namespaces.
为了解决这个问题,我创建了 gem I18nLazyLookup。它允许您对自己的自定义命名空间使用延迟查找。
Instead of using t, you can use t_scoped('welcome_flash'), and that would automatically resolve the scope to en.controllers.users.show. It also works for views and mailers, and you can customise the namespace the way you like.
t您可以使用t_scoped('welcome_flash'), 而不是 using ,这会自动将范围解析为en.controllers.users.show。它也适用于视图和邮件程序,您可以按照自己喜欢的方式自定义命名空间。
回答by mliebelt
Your question is not easy to answer, and there is not much material available on that topic. I have found the best resources are:
你的问题不容易回答,而且关于该主题的资料不多。我发现最好的资源是:
- Rails Styleguide, section Internationalization
- There are a lot of resources in the I18n wiki, but I don't have found there some that answer your questions.
- Rails 风格指南,国际化部分
- I18n wiki中有很多资源,但我没有找到可以回答您问题的资源。
So I will give it a try directly here:
所以我会直接在这里试一试:
Navigation
I think you mean here the navigation elements like breadcrumbs, tabs, ... You have to define views for them, and stick then to the rule to move all view elements in separate files in the directory
views(see the styleguide for the rule).Button text (save changes, create account, etc)
View elements, go into the same files as well. If you use the same buttons in different views, define a common file, and use that then.
Error messages from controller flash
I would use the same rule as for views. Define a separate directory, include there the files for the controllers.
How to add multi-word keys. Do I use a space or an underscore? For exmaple, t(".update button")) or t(".update_button")
I personally would prefer to use
.update_button, not.update button, because it makes more explicit that this is one key.
导航
我想你在这里的意思是导航元素,如面包屑,标签,......你必须为它们定义视图,然后遵守规则将所有视图元素移动到目录中的单独文件中
views(请参阅规则的样式指南)。按钮文本(保存更改、创建帐户等)
查看元素,也进入相同的文件。如果您在不同的视图中使用相同的按钮,请定义一个公共文件,然后使用该文件。
来自控制器闪存的错误消息
我会使用与视图相同的规则。定义一个单独的目录,在那里包含控制器的文件。
如何添加多字键。我使用空格还是下划线?例如,t(".update button")) 或 t(".update_button")
我个人更喜欢使用
.update_button,而不是.update button,因为它更明确地表明这是一个键。
回答by Damien MATHIEU
Editing directly the yaml files leads to messy and unreadable files.
Moreover, it'll be difficult for you to provide access to translators if, someday, you want a non-developer to add a new language.
直接编辑 yaml 文件会导致文件混乱且无法读取。
此外,如果有一天您希望非开发人员添加一种新语言,那么您将很难访问翻译人员。
I would recommend using localeapp, which generates a single yaml file.
But allows you to easily see and manage your translations in a web interface.
And to create additional access to translators.
我建议使用localeapp,它会生成一个 yaml 文件。
但允许您在 Web 界面中轻松查看和管理您的翻译。
并创建对翻译人员的额外访问。
回答by Cyril Duchon-Doris
Coming several years after the battle, but here is a (somewhat totally) different answer.
在战斗几年后到来,但这是一个(有点完全)不同的答案。
To begin with, I do not like the standard t('.xxx')style with the default namespace based on the file structure. I also don't really like the categorisation of translations depending on the DOM structure. While this is a nice approach for very structured translations, it is often repetitive, and not very intuitive.
首先,我不喜欢t('.xxx')基于文件结构的默认命名空间的标准样式。我也不喜欢根据 DOM 结构对翻译进行分类。虽然这对于非常结构化的翻译来说是一种很好的方法,但它通常是重复的,而且不是很直观。
I'd rather regroup my translations into more useful categories, so as to make it easier for my translators, because they can work on concrete themes, rather than some weird styles (some translators do not even know what MVC means)
我宁愿将我的翻译重新组合成更有用的类别,以便让我的译者更容易,因为他们可以处理具体的主题,而不是一些奇怪的风格(有些译者甚至不知道 MVC 是什么意思)
so my translation file is structured like this
所以我的翻译文件的结构是这样的
fr:
theme1:
theme11:
translationxxx: blabla
theme2:
translationyyy: blabla
Depending on the needs, the "themes" can be a model, a more abstract context, etc. that is the most intuitive for the translators.
根据需要,“主题”可以是对译者最直观的模型、更抽象的上下文等。
Because this would be a hassle to write everytime the scope in my views, I have added some convenience methods in my helpers to have a stack based translation context.
因为每次在我的视图中编写范围都会很麻烦,所以我在我的助手中添加了一些方便的方法来拥有基于堆栈的翻译上下文。
- I push/pop translation scopes on a stack in my views by calling
t_scope([new_scope]andpop_t - I override the
thelper to use the last scope of the stack
- 我通过调用
t_scope([new_scope]和pop_t - 我覆盖了
t助手以使用堆栈的最后一个范围
The code for the translation scoping methods is available in that answer
该答案中提供了翻译范围方法的代码

