Pluralisation i18n

Je veux pouvoir traduire des chaînes pluralisées dans i18n en rails. Une chaîne peut être:

You have 2 kids 

ou

 You have 1 kid 

Je sais que je peux utiliser la méthode d’assistance pluralize, mais je veux intégrer cela dans des traductions i18n afin de ne plus avoir à me soucier de mes vues à tout moment. J’ai lu que :count est en quelque sorte utilisé dans les traductions pour le pluriel, mais je ne trouve aucune ressource réelle sur la façon dont il est implémenté.

Notez que je sais que je peux passer une variable dans une chaîne de traduction. J’ai aussi essayé quelque chose comme:

  pluralize(1, 'kid') %> 

Ce qui fonctionne bien, mais a un problème fondamental de la même idée. Je dois spécifier la chaîne 'kid' dans l’assistant pluralize. Je ne veux pas faire cela car cela conduira à voir les problèmes à l’avenir. Au lieu de cela, je veux tout garder dans la traduction et rien dans la vue.

Comment puis je faire ça ?

    Essaye ça:

    en.yml :

     en: misc: kids: zero: no kids one: 1 kid other: %{count} kids 

    Dans une vue:

     You have <%= t('misc.kids', :count => 4) %> 

    Réponse mise à jour pour les langages à pluralisation multiple (testé avec Rails 3.0.7):

    Fichier config/initializers/pluralization.rb :

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

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

    Fichier config/locales/en.yml :

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

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

    J’espère que les programmeurs russophones Ruby on Rails pourront le trouver. Je veux juste partager ma propre formule de pluralisation russe très précise. Il repose sur les spécifications Unicode . Voici le contenu du fichier config/locales/plurals.rb uniquement, tout le rest doit être fait comme dans la réponse ci-dessus.

     {: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 } } } } } 

    Les locuteurs natifs peuvent apprécier des cas tels que 111 et 121 . Et voici les résultats du test:

    • zero: 0 запросов / куриц / яблок
    • un: 1 запрос / курица / яблоко
    • quelques: 3 запроса / курицы / яблока
    • beaucoup: 5 запросов / куриц / яблок
    • un: 101 запрос / курица / яблоко
    • quelques: 102 запроса / курицы / яблока
    • Nombreux: 105 запросов / куриц / яблок
    • nombreux: 111 запросов / куриц / яблок
    • beaucoup: 119 запросов / куриц / яблок
    • un: 121 запрос / курица / яблоко
    • quelques: 122 запроса / курицы / яблока
    • beaucoup: 125 запросов / куриц / яблок

    Merci pour la réponse initiale!

    Tout d’abord, rappelez-vous que le nombre de formes au pluriel dépend de la langue , pour l’anglais il y en a deux, pour le roumain, il y en a 3 et pour l’arabe, il y en a 6!

    Si vous voulez pouvoir utiliser correctement les formes plurielles, vous devez utiliser gettext .

    Pour Ruby et les rails, vous devriez vérifier ceci http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html

    Rails 3 gère cela de manière robuste avec la considération CLDR et la variable d’interpolation de comptage. Voir http://guides.rubyonrails.org/i18n.html#pluralization

     # in view t('actors', :count => @movie.actors.size) # locales file, ie config/locales/en.yml en: actors: one: Actor other: Actors 

    Il existe en réalité une alternative à l’approche lourde de l’i18n. La solution s’appelle Tr8n.

    Votre code ci-dessus serait simplement:

      <%= tr("You have {num || kid}", num: 1) %> 

    C’est tout. Pas besoin d’extraire vos clés de votre code et de les conserver dans des ensembles de ressources, inutile d’implémenter des règles de pluralisation pour chaque langue. Tr8n est livré avec des règles de contexte numériques pour toutes les langues. Il comprend également des règles de genre, des règles de liste et des cas de langue.

    La définition complète de la clé de traduction ci-dessus ressemblerait à ceci:

      <%= tr("You have {num:number || one: kid, other: kids}", num: 1) %> 

    Mais puisque nous voulons gagner de la place et du temps, num est automatiquement mappé sur des règles numériques et il n’est pas nécessaire de fournir toutes les options pour les valeurs de la règle. Tr8n est livré avec des pluralizers et des inflectors qui feront le travail à la volée.

    La traduction de votre clé en russe serait simplement:

      "У вас есть {num || ребенок, ребенка, детей}" 

    Au fait, votre traduction serait inexacte dans les langues qui ont des règles spécifiques au genre. Par exemple, en hébreu, vous devrez spécifier au moins 2 traductions pour votre exemple, car “Vous” serait différent selon le sexe de l’utilisateur. Tr8n le gère très bien. Voici une translittération des traductions en hébreu:

      "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}} 

    Ainsi, votre seule clé anglaise, dans ce cas, nécessite 4 traductions. Toutes les traductions sont effectuées dans leur contexte – vous n’avez pas à casser la phrase. Tr8n dispose d’un mécanisme pour mapper une clé à plusieurs traductions en fonction de la langue et du contexte, le tout à la volée.

    Une dernière chose. Et si vous deviez rendre la partie compte en gras? Ce serait simplement:

     <%= tr("You have [bold: {num || kid}]", num: 1, bold: "{$0}") %> 

    Juste au cas où vous souhaiteriez redéfinir votre “gras” plus tard – ce serait très simple – vous n’aurez pas à parcourir tous vos fichiers YAML et à les modifier – vous le faites simplement au même endroit.

    Pour en savoir plus, veuillez jeter un coup d’œil ici:

    https://github.com/tr8n/tr8n_rails_clientsdk

    Disclosure: Je suis le développeur et le mainteneur du framework Tr8n et de toutes ses bibliothèques.

    Anglais

    Ça marche juste de la boîte

    en.yml :

     en: kid: one: '1 kid' other: '%{count} kids' 

    Utilisation (vous pouvez bien sûr ignorer I18n dans un fichier de vue):

     > I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids" 

    Russe (et autres langues avec plusieurs formes plurielles)

    Installez rails-18n gem et ajoutez des traductions à vos fichiers .yml comme dans l’ exemple :

    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: '' => "дети" 

    À propos de Redmine. Si vous copiez des règles de fichier de pluralisation dans config / locales / as plurals.rb et d’autres noms de région différents (ru.rb, pl.rb .. etc), cela ne fonctionnera pas. Vous devez renommer les règles de fichier en ‘locale’.rb ou changer de méthode dans le fichier /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 

    et si vous avez de plus vieux redmine, ajoutez

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