我希望能够在rails中翻译i18n中的复数字符串。字符串可以是:
You have 2 kids
或
You have 1 kid
我知道我可以使用复数辅助方法,但我希望将其嵌入到i18n翻译中,以便我在将来的任何时候都不必弄乱我的观点。我读到:count
以某种方式用于复数的翻译,但我找不到任何关于它如何实现的真实资源。
请注意,我知道我可以在翻译字符串中传递变量。我也尝试过这样的事情:
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
哪个工作正常,但有一个相同想法的根本问题。我需要在pluralize helper中指定字符串'kid'
。我不想这样做,因为它将导致将来查看问题。相反,我想保留翻译中的所有内容,而不是视图中的任何内容。
我该怎么做?
答案 0 :(得分:166)
试试这个:
en.yml
:
en:
misc:
kids:
zero: no kids
one: 1 kid
other: %{count} kids
在视图中:
You have <%= t('misc.kids', :count => 4) %>
更新了多个复数的语言答案(使用Rails 3.0.7测试):
档案 config/initializers/pluralization.rb
:
require "i18n/backend/pluralization"
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
档案 config/locales/plurals.rb
:
{:ru =>
{ :i18n =>
{ :plural =>
{ :keys => [:one, :few, :other],
:rule => lambda { |n|
if n == 1
:one
else
if [2, 3, 4].include?(n % 10) &&
![12, 13, 14].include?(n % 100) &&
![22, 23, 24].include?(n % 100)
:few
else
:other
end
end
}
}
}
}
}
#More rules in this file: https://github.com/svenfuchs/i18n/blob/master/test/test_data/locales/plurals.rb
#(copy the file into `config/locales`)
档案 config/locales/en.yml
:
en:
kids:
zero: en_zero
one: en_one
other: en_other
档案 config/locales/ru.yml
:
ru:
kids:
zero: ru_zero
one: ru_one
few: ru_few
other: ru_other
<强>测试强>:
$ rails c
>> I18n.translate :kids, :count => 1
=> "en_one"
>> I18n.translate :kids, :count => 3
=> "en_other"
>> I18n.locale = :ru
=> :ru
>> I18n.translate :kids, :count => 1
=> "ru_one"
>> I18n.translate :kids, :count => 3
=> "ru_few" #works! yay!
>> I18n.translate :kids, :count => 5
=> "ru_other" #works! yay!
答案 1 :(得分:33)
我希望讲俄语的Ruby on Rails程序员能找到这个。只是想分享我自己非常精确的俄罗斯复数公式。它基于Unicode Specs。
以下是config/locales/plurals.rb
文件的内容,其他所有内容都应与上面的答案相同。
{:ru =>
{ :i18n =>
{ :plural =>
{ :keys => [:zero, :one, :few, :many],
:rule => lambda { |n|
if n == 0
:zero
elsif
( ( n % 10 ) == 1 ) && ( ( n % 100 != 11 ) )
# 1, 21, 31, 41, 51, 61...
:one
elsif
( [2, 3, 4].include?(n % 10) \
&& ![12, 13, 14].include?(n % 100) )
# 2-4, 22-24, 32-34...
:few
elsif ( (n % 10) == 0 || \
![5, 6, 7, 8, 9].include?(n % 10) || \
![11, 12, 13, 14].include?(n % 100) )
# 0, 5-20, 25-30, 35-40...
:many
end
}
}
}
}
}
母语人士可能会喜欢111
和121
等案例。
在这里测试结果:
感谢您的初步回答!
答案 2 :(得分:11)
首先,请记住复数形式的数量取决于语言,英语有两个,罗马尼亚语有3个,阿拉伯语有6个。
如果您希望能够正确使用复数表格,则必须使用gettext
。
对于Ruby和rails,您应该查看http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
答案 3 :(得分:8)
Rails 3通过CLDR考虑和计数插值变量来稳健地处理这个问题。见http://guides.rubyonrails.org/i18n.html#pluralization
# in view
t('actors', :count => @movie.actors.size)
# locales file, i.e. config/locales/en.yml
en:
actors:
one: Actor
other: Actors
答案 4 :(得分:2)
实际上有一种替代麻烦的i18n方法。该解决方案称为Tr8n。
您的上述代码只是:
<%= tr("You have {num || kid}", num: 1) %>
那就是它。无需从代码中提取密钥并将其保存在资源包中,无需为每种语言实现复数规则。 Tr8n附带所有语言的数字上下文规则。它还附带性别规则,列表规则和语言案例。
上述翻译密钥的完整定义实际上如下所示:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
但是由于我们想节省空间和时间,num会自动映射到数字规则,并且不需要为规则值提供所有选项。 Tr8n配备了多元化和变形器,可以随时为您完成工作。
您的俄语密钥翻译只需:
"У вас есть {num || ребенок, ребенка, детей}"
顺便说一下,对于具有性别特定规则的语言,您的翻译不准确。 例如,在希伯来语中,您实际上必须为您的示例指定至少2个翻译,因为&#34;您&#34;将根据观看用户的性别而有所不同。 Tr8n处理得非常好。以下是希伯来语翻译的音译:
"Yesh leha yeled ahad" with {context: {viewing_user: male, num: one}}
"Yesh leha {num} yeladim" with {context: {viewing_user: male, num: other}}
"Yesh lah yeled ahad" with {context: {viewing_user: female, num: one}}
"Yesh lah {num} yeladim" with {context: {viewing_user: female, num: other}}
因此,在这种情况下,您的单个英语密钥需要4个翻译。所有翻译都是在上下文中完成的 - 您不必打破句子。 Tr8n有一种机制,可以根据语言和上下文将一个键映射到多个翻译 - 所有这些都是动态完成的。
最后一件事。如果你必须把计数部分加粗怎么办?它只是:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
万一你要重新定义你的&#34;粗体&#34;之后 - 这将非常简单 - 您不必浏览所有YAML文件并进行更改 - 您只需在一个地方完成。
要了解更多信息,请点击此处:
https://github.com/tr8n/tr8n_rails_clientsdk
披露:我是Tr8n框架及其所有库的开发者和维护者。
答案 5 :(得分:0)
开箱即用works
<强> en.yml 强>:
en:
kid:
one: '1 kid'
other: '%{count} kids'
用法(当然,您可以在视图文件中跳过I18n):
> I18n.t :kid, count: 1
=> "1 kid"
> I18n.t :kid, count: 3
=> "3 kids"
安装rails-18n gem并在.yml
文件中添加翻译,如example:
<强> ru.yml 强>:
ru:
kid:
zero: 'нет детей'
one: '%{count} ребенок'
few: '%{count} ребенка'
many: '%{count} детей'
other: 'дети'
用法:
> I18n.t :kid, count: 0
=> "нет детей"
> I18n.t :kid, count: 1
=> "1 ребенок"
> I18n.t :kid, count: 3
=> "3 ребенка"
> I18n.t :kid, count: 5
=> "5 детей"
> I18n.t :kid, count: 21
=> "21 ребенок"
> I18n.t :kid, count: 114
=> "114 детей"
> I18n.t :kid, count: ''
=> "дети"
答案 6 :(得分:0)
关于Redmine。如果您在config / locales /中将复数文件规则复制为plurals.rb,而其他与语言环境名称不同的规则(ru.rb,pl.rb等)则无法使用。 您必须将文件规则重命名为'locale'.rb或更改文件/lib/redmine/i18n.rb
中的方法def init_translations(locale)
locale = locale.to_s
paths = ::I18n.load_path.select {|path| File.basename(path, '.*') == locale}
load_translations(paths)
translations[locale] ||= {}
end
如果您使用的是旧版的Redmine,请添加
module Implementation
include ::I18n::Backend::Base
**include ::I18n::Backend::Pluralization**