Je veux pouvoir traduire des chaînes plurielles 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 l'intégrer dans les traductions i18n afin de ne pas avoir à gâcher mes vues à tout moment dans le futur. J'ai lu que :count
c'est en quelque sorte utilisé dans les traductions pour le pluriel, mais je ne trouve pas de ressources réelles sur la façon dont il est mis en œuvre.
Notez que je sais que je peux passer une variable dans une chaîne de traduction. J'ai aussi essayé quelque chose comme:
<%= t 'misc.kids', :kids_num => 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 de pluralisation. Je ne veux pas faire cela parce que cela mènera à voir des problèmes dans le futur. Au lieu de cela, je veux garder tout dans la traduction et rien dans la vue.
Comment puis je faire ça ?
"#{....}"
ne sont pas nécessaires dans le code ci-dessus.<%= t 'misc.kids', :kids_num => pluralize(1, t('kid')) %>
. Peut-être que cela n'a pas fonctionné en 2011 (!) Mais c'est sûr maintenant sur Rails 5.2.2Réponses:
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 langues à pluralisation multiple (testée 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!
la source
%{count}
fonctionner, j'ai dû utiliser des citations autour de tout le bloc, c'est-à-dire.one: "%{count} kid"
J'espère que les programmeurs de Ruby on Rails russophones pourront le trouver. Je veux juste partager ma propre formule de pluralisation russe très précise. Il est basé sur les spécifications Unicode . Voici le contenu du
config/locales/plurals.rb
fichier uniquement, tout le reste 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
et121
. Et voici les résultats du test:Merci pour la réponse initiale!
la source
config/locales/plurals.rb
plutôt queconfig/initializers/pluralization.rb
Tout d'abord, rappelez-vous que le nombre de formes plurielles 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
la source
Rails 3 gère cela de manière robuste avec la considération CLDR et la variable d'interpolation de compte. Voir 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
la source
Anglais
Cela fonctionne juste hors de la boîte
en.yml :
en: kid: one: '1 kid' other: '%{count} kids'
Utilisation (vous pouvez ignorer I18n dans un fichier de vue, bien sûr):
> I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids"
Russe (et autres langues avec plusieurs formes plurielles)
Installez le gem rails-18n et ajoutez des traductions à vos
.yml
fichiers 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: '' => "дети"
la source
Il existe en fait une alternative à la lourde approche i18n. La solution s'appelle Tr8n.
Votre code ci-dessus serait simplement:
<%= tr("You have {num || kid}", num: 1) %>
C'est ça. Pas besoin d'extraire vos clés de votre code et de les maintenir dans des ensembles de ressources, pas besoin 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 est également livré avec 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 en fait à ceci:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
Mais puisque nous voulons économiser de l'espace 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 règle. Tr8n est livré avec des pluraliseurs et des inflecteurs qui feront le travail pour vous à la volée.
La traduction de votre clé en russe serait simplement:
"У вас есть {num || ребенок, ребенка, детей}"
En passant, votre traduction serait inexacte dans les langues qui ont des règles spécifiques au genre. Par exemple, en hébreu, vous devrez en fait spécifier au moins 2 traductions pour votre exemple, car «Vous» serait différent en fonction du sexe de l'utilisateur qui regarde. Tr8n le gère très bien. Voici une translittération des traductions hébraïques:
"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}}
Donc, votre clé anglaise unique, dans ce cas, nécessite 4 traductions. Toutes les traductions sont effectuées en contexte - vous n'avez pas à casser la phrase. Tr8n a 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 comptage en gras? Ce serait simplement:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
Juste au cas où vous voudriez redéfinir votre "gras" plus tard - ce serait très facile - vous n'aurez pas à parcourir tous vos fichiers YAML et à les modifier - vous le faites simplement en un seul endroit.
Pour en savoir plus, jetez un œil ici:
https://github.com/tr8n/tr8n_rails_clientsdk
Divulgation: Je suis le développeur et le mainteneur du framework Tr8n et de toutes ses bibliothèques.
la source
À propos de Redmine. Si vous copiez les règles de fichier de pluralisation dans config / locales / en tant que plurals.rb et autres pas les mêmes que le nom de locale (ru.rb, pl.rb .. etc.), cela ne fonctionne 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 une ancienne redmine, ajoutez
module Implementation include ::I18n::Backend::Base **include ::I18n::Backend::Pluralization**
la source