ruby-on-railsinternationalizationrails-i18npluralizeplural

i18n Pluralization


I want to be able to translate pluralized strings in i18n in rails. A string can be :

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 :count is somehow used in translations for plural, but I can't find any real resources on how it gets implemented.

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.

How can I do that ?


Solution

  • Try this:

    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):

    File config/initializers/pluralization.rb:

    require "i18n/backend/pluralization" 
    I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
    

    File 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`)
    

    File config/locales/en.yml:

    en:
      kids:
        zero: en_zero
        one: en_one
        other: en_other
    

    File 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!