Ruby on rails i18n多元化

Ruby on rails i18n多元化,ruby-on-rails,internationalization,rails-i18n,pluralize,plural,Ruby On Rails,Internationalization,Rails I18n,Pluralize,Plural,我希望能够在rails中翻译i18n中的复数字符串。字符串可以是: You have 2 kids 或 我知道我可以使用pluralizehelper方法,但我想将其嵌入到i18n翻译中,这样我就不必在将来的任何时候弄乱我的观点。我读到,:count以某种方式被用于复数翻译,但我找不到任何关于它如何实现的真正资源 请注意,我知道我可以在翻译字符串中传递变量。我也试过这样的方法: <%= t 'misc.kids', :kids_num => pluralize(1, 'kid')

我希望能够在rails中翻译i18n中的复数字符串。字符串可以是:

You have 2 kids

我知道我可以使用pluralizehelper方法,但我想将其嵌入到i18n翻译中,这样我就不必在将来的任何时候弄乱我的观点。我读到,
:count
以某种方式被用于复数翻译,但我找不到任何关于它如何实现的真正资源

请注意,我知道我可以在翻译字符串中传递变量。我也试过这样的方法:

<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
pluralize(1,'kid')%%>
这很好,但有一个基本问题是相同的想法。我需要在pluralize助手中指定字符串
'kid'
。我不想这样做,因为这将导致未来的问题。取而代之的是,我想把所有的东西都保留在译文中,什么都不保留在视图中

我该怎么做呢?

试试这个:

en.yml

en:
  misc:
    kids:
      zero: no kids
      one: 1 kid
      other: %{count} kids
从某种角度来看:

You have <%= t('misc.kids', :count => 4) %>
文件
config/locales/plurals.rb

require "i18n/backend/pluralization" 
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
{: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
ru:
  kids:
    zero: ru_zero
    one: ru_one
    few: ru_few
    other: ru_other
文件
config/locales/ru.yml

en:
  kids:
    zero: en_zero
    one: en_one
    other: en_other
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! 
en:
  kid:
    one: '1 kid'
    other: '%{count} kids'
ru:
  kid:
    zero: 'нет детей'
    one: '%{count} ребенок'
    few: '%{count} ребенка'
    many: '%{count} детей'
    other: 'дети'

首先,请记住,复数形式的数量取决于语言,英语有两种,罗马尼亚语有3种,阿拉伯语有6种

如果你想正确使用复数形式,你必须使用
gettext


对于Ruby和rails,您应该检查一下这一点,rails 3通过考虑CLDR和计数插值变量来处理这一点。看


实际上,除了繁琐的i18n方法之外,还有一种替代方法。该解决方案称为Tr8n

您的上述代码将是:

 <%= tr("You have {num || kid}", num: 1) %>
 "У вас есть {num || ребенок, ребенка, детей}"
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
顺便说一句,你的翻译在有性别规定的语言中是不准确的。 例如,在希伯来语中,您实际上必须为您的示例指定至少两种翻译,因为“you”将根据查看用户的性别而有所不同。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 {num || kid}", num: 1) %>
 "У вас есть {num || ребенок, ребенка, детей}"
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>

万一你以后想重新定义你的“粗体”,那会很容易,你不需要检查所有的YAML文件并修改它们,你只需要在一个地方做

要了解更多信息,请查看以下内容:


披露:我是Tr8n框架及其所有库的开发者和维护者。

我希望讲俄语的RubyonRails程序员能找到这一点。我只想分享一下我自己非常精确的俄罗斯多元化公式。它基于。 这里仅是
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
等案例。 下面是测试结果:

  • 零:0ззззззззззззззззззз
  • 一:1зззззаС/зааааа/зааааа
  • 少数:3зззззааа/заааааа1072
  • 许多:5ззззззззззззззз1079
  • 一:101ззззззС/ззззззззз
  • 少数:102зззззааа/баааааа1072
  • 许多:105ззззззззззззззз1073
  • 许多:111ззззззззззззззз1073
  • 许多:119зззззззззззззззз1079
  • 一:121ззззззС/ззааааа/б
  • 少数:122
  • 许多:125ззззззззззззззз1073
谢谢你的初步回答

英式 这是开箱即用的

en.yml

$ 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! 
en:
  kid:
    one: '1 kid'
    other: '%{count} kids'
ru:
  kid:
    zero: 'нет детей'
    one: '%{count} ребенок'
    few: '%{count} ребенка'
    many: '%{count} детей'
    other: 'дети'
用法(当然,您可以跳过视图文件中的I18n):

俄语(和其他多种复数形式的语言) 安装gem并将翻译添加到
.yml
文件中,如下所示:

ru.yml

$ 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! 
en:
  kid:
    one: '1 kid'
    other: '%{count} kids'
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: ''
 => "дети"

关于雷德明。如果复制config/locales/as plurals.rb中的复数文件规则以及其他与区域名称不同的规则(ru.rb、pl.rb..etc),则这些规则不起作用。 您必须将文件规则重命名为“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
如果你有老红矿,加上

module Implementation
        include ::I18n::Backend::Base
        **include ::I18n::Backend::Pluralization**

请注意,上面的代码中不需要“interpolator”和引号
“#{….}”
。您的方法是错误的,因为您假设其他语言的复数形式与英语中的一样。请参阅,以获得正确的方法。Sorin,谢谢您的回答,我只是不想使用gettext进行此操作。我认为Zabba的解决方案非常适合我在i18n上的需要。Rails 3使用CLDR和“count”插值变量处理的更可靠:几年后,但您也可以对字符串“kid”使用翻译,因此您有:
pluralize(1,t('kid'))%%>
。也许这在2011年不起作用(!),但现在在Rails 5.2.2上确实起作用了,不过这在很多语言中都不起作用。多元化真的很复杂,因此我认为我的答案更合适。@sorin,更新了我的答案以使用多种多元化规则。没关系,但现在你有了一份新的全职工作,来维护多元化词典!。这太棒了!为了使
%{count}
工作,我必须在整个块周围使用引号,即
一个:“%{count}kid”
@ThePablick,是的,因为“/initializer”目录中的文件只在http服务器启动时加载一次。Sorin,这也是我的想法,但这似乎是通过遵循CLDR格式()来解决的。我错了吗?还有第1、第2、第3、第4、第11、第12和第13票,还有第21、第22、第23票等等。我希望我知道投反对票的是什么,回答