This StackOverflow问题让我对Rails i18n文件的优秀结构有了深思,所以我想我会分享另一个结构来重构Rails i18n yml文件供您考虑/批评。
鉴于我想
t('.some_translation')
,并了解应用中翻译的使用情况,对于 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
我可以看到存在重大的重复,并且诸如“电子邮件”和“密码”之类的词语的上下文是明确的并且在它们各自的视图中具有相同的含义。如果我决定将“电子邮件”更改为“电子邮件”,那么必须去更改它们会有点烦人,所以我想重构字符串以引用某种字典。那么,如何使用这样的&
个锚点将字典哈希添加到文件的顶部:
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
您仍然可以继续使用静态字符串(例如上面的“用户”),但只要您在视图中获得完全相同的单词/短语的多个实例,就可以将其重构为字典。如果基本语言中的键的字典翻译对目标语言没有意义,则只需将目标语言中的引用值更改为静态字符串,或将其作为额外条目添加到目标语言的字典中。我确信每种语言的字典都可以重构成另一个文件,如果它们变得太大而且不实用(只要它在翻译文件的顶部重新导入,以便引用有效)。
这种结构化i18n yaml文件的方式似乎适用于我尝试过的一些本地测试应用程序。我希望美妙的Localeapp将来会为这种锚定/引用提供支持。但无论如何,所有这些词典谈话都不可能是一个原创的想法,所以YAML中的锚点引用还有其他问题吗,或者可能只是整个“字典”概念?或者,如果你有超出Rails默认i18n约定的需求,那么完全删除默认后端并用Redis或其他东西替换它会更好吗?
修改:
我想尝试解决下面评论中提到的tigrish的工作流程示例,而不是在他的回答下面的另一条评论。如果我似乎没有得到积分或者我只是天真,请原谅我:
第1点:您有一个ActiveRecord模型的常规“name”属性,它们都只是指向通用字典中的名称:
dictionary:
name: &name Name
activerecord:
attributes:
name: *name
user:
name: *name
product:
name: *name
第2点:仅需要更改用户模型的名称。其他名字保持不变。
选项1 :在后端保持模型字段名称相同,只需更改它指向的前端翻译。
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
迁移。
dictionary:
name: &name Name
full_name: &full_name Full Name
activerecord:
attributes:
name: *name
user:
full_name: *full_name
product:
name: *name
选项3 :如果您想要非常彻底,请将“名称”中包含的信息重构为单独的数据库/ Activemodel字段,这些字段需要新的字典条目和迁移。您可以决定如何显示“全名”:
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的示例
开始选项1 :模型字段名称相同,只需更改前端翻译。
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
。
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中是一个坏主意应用程序。难以阅读?维修噩梦?如果我使用(我认为是)该语言的一个特征,它真的被认为是“黑客文件格式”吗?
再次感谢tigrish让我把这一切都拿出来。
答案 0 :(得分:11)
TLDNR;不要破解你的文件格式,改进rails帮助,并帮助建立标准化的密钥结构!
TLDR;
不想在你的游行中下雨,但我对这种技术有一些问题。在哪里使用点快捷方式以及铁轨助手的键结构如何不同的困境可能有点令人费解。
据我了解,问题基本上是关于干掉你的语言环境文件并使用YAML语言的一个功能来实现这个目的。
首先,锚点只能保证适用于YAML,所以这个解决方案不能一般地应用于I18n。如果使用不同的后端,此技术可能不可行。无论是SQL,Redis还是Json,我都不知道它们中是否有任何类型的符号链接功能。而且事实上,翻译实际上是重复的。
我遇到的第二个也是更大的问题是关于语言学。您的示例表明所有这些术语在上下文和含义上完全相同。不幸的是,这只是非常简单的例子。
毫无疑问,随着您的应用程序的增长或添加其他语言,您会发现Person的“name”属性必须与Book的“name”属性不同,在英语中我们称之为“title” - 好吧,这个例子真的很复杂;)但是当你混合使用越来越多的语言时,这种情况确实经常发生,理想情况下,我们需要一种处理它的通用方法。
我认为在很大程度上,复杂性来自使用不同默认值的rails帮助程序,而没有关键结构的约定。
回到你的例子,你提到了我认为非常不同的两件事:activerecord属性翻译使用rails助手和使用点快捷键的视图翻译。
让我举一个超常频繁的工作流程示例:
我们无法用共享的“字典”处理这种情况。当然我们的语言环境文件是干的,但我们的语言/翻译问题与我们的开发人员关注的问题大不相同(遗憾的是)。
从好的方面来说,我们可以更清楚地了解我们所描述的内容,并在我们的关键结构和工具中反映出来 - 对我而言,这是前进的方向! :)
答案 1 :(得分:5)
我只是发布一个名为i18n-recursive-lookup的gem,它允许定义通过引入特殊的嵌入式标记$ {}
来包含对其他定义的嵌入式引用https://github.com/annkissam/i18n-recursive-lookup
使用它你可以将你的例子重构为:
dictionary:
email: Email
name: Name
password: Password
confirmation: Confirmation
activerecord:
attributes:
user:
email: ${dictionary.email}
name: ${dictionary.name}
password: ${dictionary.password}
password_confirmation: ${dictionary.confirmation}
models:
user: User
users:
fields:
email: ${dictionary.email}
name: ${dictionary.name}
password: ${dictionary.password}
confirmation: ${dictionary.confirmation}
sessions:
new:
email: ${dictionary.email}
password: ${dictionary.password}
好消息是,一旦编译,翻译就会被写回翻译商店,以便所有插值/递归查找都会发生一次。
我知道这可能无法回答关于干燥翻译的“正确”方式的更多哲学问题,但我认为这是使用& amp;的更好的替代方法。标签参考YML hack。
答案 2 :(得分:0)
改进重新呈现YAML文件,特别是对于那些拥有多种模型的人:
ru:
dictionary:
name: &name "Имя"
title_ru: &title_ru "Заголовок (ru)"
title_en: &title_en "Заголовок (en)"
content_ru: &content_ru "Содержание (ru)"
content_en: &content_en "Содержание (en)"
role: &role "Роль"
created_at: &created_at "Создано в"
updated_at: &updated_at "Обновлено в"
published: &published "Опубликовано"
nomination: &nomination
name: *name
title_ru: *title_ru
title_en: *title_en
post: &post
content_ru: *content_ru
content_en: *content_en
published: *published
dates: &dates
created_at: *created_at
updated_at: *updated_at
activerecord:
attributes:
article:
<<: *nomination
<<: *post
<<: *dates
user:
<<: *dates
role: *role
email: "Электропочта"
用户link
答案 3 :(得分:0)
我刚刚发布了名为dry_i18n的宝石:https://rubygems.org/gems/dry_i18n
我创建了这个gem来解决你要求的问题。有了这个宝石,你甚至可以重复使用带插值的键并嵌套它们。
我希望它很有用。