Ruby-on-rails i18n 多元化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6166064/
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
i18n Pluralization
提问by Spyros
I want to be able to translate pluralized strings in i18n in rails. A string can be :
我希望能够在 rails 中翻译 i18n 中的复数字符串。一个字符串可以是:
You have 2 kids
or
或者
You have 1 kid
I know that I can use pluralize helper method, but I want to embed this in i18n translations so that I don't have to mess up with my views at any point in the future. I read that :countis somehow used in translations for plural, but I can't find any real resources on how it gets implemented.
我知道我可以使用复数辅助方法,但我想将它嵌入到 i18n 翻译中,这样我就不必在将来的任何时候弄乱我的观点。我读到它:count以某种方式用于复数的翻译,但我找不到任何关于它如何实现的真正资源。
Notice that I know that I can pass a variable in a translation string. I also tried something like :
请注意,我知道我可以在翻译字符串中传递一个变量。我也尝试过类似的东西:
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
Which works fine, but has a fundamental problem of the same idea. I need to specify the string 'kid'in the pluralize helper. I don't want to do that because it will lead to view problems in the future. Instead I want to keep everything in the translation and nothing in the view.
哪个工作正常,但有一个相同想法的基本问题。我需要'kid'在复数帮助器中指定字符串。我不想这样做,因为它会导致将来出现问题。相反,我想在翻译中保留所有内容,而在视图中不保留任何内容。
How can I do that ?
我怎样才能做到这一点 ?
回答by Zabba
Try this:
尝试这个:
en.yml:
en.yml:
en:
misc:
kids:
zero: no kids
one: 1 kid
other: %{count} kids
In a view:
在一个观点:
You have <%= t('misc.kids', :count => 4) %>
Updated answer for languages with multiple pluralization (tested with Rails 3.0.7):
更新了多重复数语言的答案(使用 Rails 3.0.7 测试):
Fileconfig/initializers/pluralization.rb:
文件config/initializers/pluralization.rb:
require "i18n/backend/pluralization"
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
Fileconfig/locales/plurals.rb:
文件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`)
Fileconfig/locales/en.yml:
文件config/locales/en.yml:
en:
kids:
zero: en_zero
one: en_one
other: en_other
Fileconfig/locales/ru.yml:
文件config/locales/ru.yml:
ru:
kids:
zero: ru_zero
one: ru_one
few: ru_few
other: ru_other
Test:
测试:
$ 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!
回答by sashaegorov
I hope Russian-speaking Ruby on Rails programmers could find this. Just want to share my own very precise Russian pluralization formula. It based on Unicode Specs.
Here is contents of config/locales/plurals.rbfile only, everything else should be done as same as in answer above.
我希望讲俄语的 Ruby on Rails 程序员可以找到这个。只是想分享我自己非常精确的俄语复数公式。它基于Unicode 规范。这里只是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
}
}
}
}
}
Native speakers may enjoy cases such as 111and 121.
And here the test results:
母语人士可能会喜欢111和等案例121。测试结果如下:
- zero: 0 запросов/куриц/яблок
- one: 1 запрос/курица/яблоко
- few: 3 запроса/курицы/яблока
- many: 5 запросов/куриц/яблок
- one: 101 запрос/курица/яблоко
- few: 102 запроса/курицы/яблока
- many: 105 запросов/куриц/яблок
- many: 111 запросов/куриц/яблок
- many: 119 запросов/куриц/яблок
- one: 121 запрос/курица/яблоко
- few: 122 запроса/курицы/яблока
- many: 125 запросов/куриц/яблок
- 零:0 запросов/куриц/яблок
- 一:1 запрос/курица/яблоко
- 少数:3 запроса/курицы/яблока
- 许多:5 запросов/куриц/яблок
- 一:101 запрос/курица/яблоко
- 少数:102 запроса/курицы/яблока
- 许多:105 запросов/куриц/яблок
- 许多:111 запросов/куриц/яблок
- 许多:119 запросов/куриц/яблок
- 一:121 запрос/курица/яблоко
- 少数:122 запроса/курицы/яблока
- 许多:125 запросов/куриц/яблок
Thanks for initial answer!
感谢您的初步答复!
回答by sorin
First, remember that number of plural forms depends on language, for English there are two, for Romanian there are 3 and for Arabic there are 6 !.
首先,请记住复数形式的数量取决于语言,英语有两个,罗马尼亚语有 3 个,阿拉伯语有 6 个 !。
If you want to be able to properly use plural forms you have to use gettext.
如果您希望能够正确使用复数形式,则必须使用gettext.
For Ruby and rails you should check this http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
对于 Ruby 和 rails,你应该检查这个http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
回答by Luke W
Rails 3 handles this robustly with CLDR consideration and count interpolation variable. See http://guides.rubyonrails.org/i18n.html#pluralization
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
回答by installero
English
英语
It just worksout of the box
这只是工作的开箱
en.yml:
.yml:
en:
kid:
one: '1 kid'
other: '%{count} kids'
Usage (you can skip I18n in a view file, of course):
用法(当然,您可以在视图文件中跳过 I18n):
> I18n.t :kid, count: 1
=> "1 kid"
> I18n.t :kid, count: 3
=> "3 kids"
Russian (and other languages with multiple plural forms)
俄语(和其他具有多种复数形式的语言)
Install rails-18ngem and add translations to your .ymlfiles as in the example:
安装rails-18ngem 并将翻译添加到您的.yml文件中,如示例所示:
ru.yml:
ru.yml:
ru:
kid:
zero: 'нет детей'
one: '%{count} ребенок'
few: '%{count} ребенка'
many: '%{count} детей'
other: 'дети'
Usage:
用法:
> 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: ''
=> "дети"
回答by Michael Berkovich
There is actually an alternative to the cumbersome i18n approach. The solution is called Tr8n.
实际上有一种替代繁琐的 i18n 方法的方法。该解决方案称为 Tr8n。
Your above code would simply be:
你上面的代码只是:
<%= tr("You have {num || kid}", num: 1) %>
That's it. No need to extract your keys from your code and maintain them in resource bundles, no need to implement pluralization rules for each language. Tr8n comes with numeric context rules for all language. It also comes with gender rules, list rules and language cases.
就是这样。无需从代码中提取密钥并将它们维护在资源包中,无需为每种语言实施复数规则。Tr8n 带有适用于所有语言的数字上下文规则。它还带有性别规则、列表规则和语言案例。
The full definition of the above translation key would actually look like this:
上述翻译键的完整定义实际上如下所示:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
But since we want to save space and time, num is automatically mapped to numeric rules and there is no need to provide all options for the rule values. Tr8n comes with pluralizers and inflectors that will do the work for you on the fly.
但由于我们要节省空间和时间,num 会自动映射到数字规则,无需为规则值提供所有选项。Tr8n 带有复数词和变形词,可以即时为您完成工作。
The translation for your key in Russian, would simply be:
您的俄语密钥的翻译只是:
"У вас есть {num || ребенок, ребенка, детей}"
By the way, your translation would be inaccurate in languages that have gender specific rules. For example, in Hebrew, you would actually have to specify at least 2 translations for your example, as "You" would be different based on the gender of the viewing user. Tr8n handles it very well. Here is a transliteration of Hebrew translations:
顺便说一句,您的翻译在具有特定性别规则的语言中会不准确。例如,在希伯来语中,您实际上必须为示例指定至少 2 个翻译,因为“您”会根据查看用户的性别而有所不同。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}}
So your single English key, in this case, needs 4 translations. All translations are done in context - you don't have to break the sentence. Tr8n has a mechanism to map one key to multiple translations based on the language and context - all done on the fly.
因此,在这种情况下,您的单个英文密钥需要 4 次翻译。所有翻译都是在上下文中完成的 - 您不必打断句子。Tr8n 有一种机制可以根据语言和上下文将一个键映射到多个翻译——所有这些都是即时完成的。
One last thing. What if you had to make the count part bold? It would simply be:
最后一件事。如果您必须将计数部分设为粗体怎么办?它只是:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{def init_translations(locale)
locale = locale.to_s
paths = ::I18n.load_path.select {|path| File.basename(path, '.*') == locale}
load_translations(paths)
translations[locale] ||= {}
end
}</strong>") %>
Just in case you want to redefine your "bold" later - it would be very easy - you won't have to go through all your YAML files and change them - you just do it in one place.
以防万一您想稍后重新定义“粗体” - 这将非常容易 - 您不必浏览所有 YAML 文件并更改它们 - 您只需在一个地方进行。
To learn more, please take a look here:
要了解更多信息,请查看这里:
https://github.com/tr8n/tr8n_rails_clientsdk
https://github.com/tr8n/tr8n_rails_clientsdk
Disclosure: I am the developer and the maintainer of Tr8n framework and all its libraries.
披露:我是 Tr8n 框架及其所有库的开发者和维护者。
回答by Vladimir Kovalev
About Redmine. If you copy pluralization file rules in config/locales/ as plurals.rb and other not same as locale name (ru.rb, pl.rb .. etc) these not work. You must rename file rules to 'locale'.rb or change method in file /lib/redmine/i18n.rb
关于 Redmine。如果您将 config/locales/ 中的复数文件规则复制为复数.rb 和其他与区域设置名称(ru.rb、pl.rb .. 等)不同的内容,则这些规则不起作用。您必须将文件规则重命名为 'locale'.rb 或更改文件 /lib/redmine/i18n.rb 中的方法
module Implementation
include ::I18n::Backend::Base
**include ::I18n::Backend::Pluralization**
and if you have older redmine, add
如果您有较旧的 redmine,请添加
##代码##
