Quiero poder traducir cadenas pluralizadas en i18n en rieles. Una cadena puede ser:
You have 2 kids
o
You have 1 kid
Sé que puedo usar el método auxiliar de pluralizar, pero quiero incrustar esto en las traducciones de i18n para no tener que estropear mis puntos de vista en ningún momento en el futuro. Leí que de :count
alguna manera se usa en traducciones para plural, pero no puedo encontrar ningún recurso real sobre cómo se implementa.
Observe que sé que puedo pasar una variable en una cadena de traducción. También probé algo como:
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
Lo cual funciona bien, pero tiene un problema fundamental de la misma idea. Necesito especificar la cadena 'kid'
en el auxiliar pluralizado. No quiero hacer eso porque generará problemas de visualización en el futuro. En cambio, quiero mantener todo en la traducción y nada en la vista.
Cómo puedo hacer eso ?
"#{....}"
no son necesarios en el código anterior.<%= t 'misc.kids', :kids_num => pluralize(1, t('kid')) %>
. Tal vez esto no funcionó en 2011 (!) Pero seguro que funciona ahora en Rails 5.2.2Respuestas:
Prueba esto:
en.yml
:en: misc: kids: zero: no kids one: 1 kid other: %{count} kids
En una vista:
You have <%= t('misc.kids', :count => 4) %>
Respuesta actualizada para idiomas con pluralización múltiple (probado con Rails 3.0.7):
Archivo
config/initializers/pluralization.rb
:require "i18n/backend/pluralization" I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
Archivo
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`)
Archivo
config/locales/en.yml
:en: kids: zero: en_zero one: en_one other: en_other
Archivo
config/locales/ru.yml
:ru: kids: zero: ru_zero one: ru_one few: ru_few other: ru_other
Prueba :
$ 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!
fuente
%{count}
funcione, tuve que usar comillas en todo el bloque, es decir.one: "%{count} kid"
Espero que los programadores de Ruby on Rails de habla rusa puedan encontrar esto. Solo quiero compartir mi propia fórmula de pluralización rusa muy precisa. Se basa en las especificaciones Unicode . Aquí está el contenido del
config/locales/plurals.rb
archivo solamente, todo lo demás debe hacerse igual que en la respuesta anterior.{: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 } } } } }
Los hablantes nativos pueden disfrutar de casos como
111
y121
. Y aquí los resultados de la prueba:¡Gracias por la respuesta inicial!
fuente
config/locales/plurals.rb
lugar deconfig/initializers/pluralization.rb
Primero, recuerde que el número de formas plurales depende del idioma , para el inglés hay dos, para el rumano hay 3 y para el árabe hay 6.
Si desea poder usar correctamente las formas plurales, debe usar
gettext
.Para Ruby y rieles, debe consultar este http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
fuente
Rails 3 maneja esto de manera robusta con la consideración CLDR y la variable de interpolación de conteo. Ver 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
fuente
Inglés
Simplemente funciona fuera de la caja
en.yml :
en: kid: one: '1 kid' other: '%{count} kids'
Uso (puede omitir I18n en un archivo de vista, por supuesto):
> I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids"
Ruso (y otros idiomas con múltiples formas plurales)
Instale la gema rails-18n y agregue traducciones a sus
.yml
archivos como en el ejemplo :ru.yml :
ru: kid: zero: 'нет детей' one: '%{count} ребенок' few: '%{count} ребенка' many: '%{count} детей' other: 'дети'
Uso:
> 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: '' => "дети"
fuente
En realidad, existe una alternativa al engorroso enfoque i18n. La solución se llama Tr8n.
Su código anterior simplemente sería:
<%= tr("You have {num || kid}", num: 1) %>
Eso es. No es necesario extraer sus claves de su código y mantenerlas en paquetes de recursos, no es necesario implementar reglas de pluralización para cada idioma. Tr8n viene con reglas de contexto numéricas para todos los idiomas. También viene con reglas de género, reglas de lista y casos de idioma.
La definición completa de la clave de traducción anterior se vería así:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
Pero como queremos ahorrar espacio y tiempo, num se asigna automáticamente a las reglas numéricas y no es necesario proporcionar todas las opciones para los valores de las reglas. Tr8n viene con pluralizadores e inflectores que harán el trabajo por usted sobre la marcha.
La traducción de su clave en ruso sería simplemente:
"У вас есть {num || ребенок, ребенка, детей}"
Por cierto, su traducción sería inexacta en idiomas que tienen reglas específicas de género. Por ejemplo, en hebreo, en realidad tendría que especificar al menos 2 traducciones para su ejemplo, ya que "Usted" sería diferente según el género del usuario que lo ve. Tr8n lo maneja muy bien. Aquí hay una transliteración de traducciones hebreas:
"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}}
Entonces, su clave única en inglés, en este caso, necesita 4 traducciones. Todas las traducciones se realizan en contexto, no es necesario romper la oración. Tr8n tiene un mecanismo para asignar una clave a múltiples traducciones según el idioma y el contexto, todo hecho sobre la marcha.
Una última cosa. ¿Y si tuvieras que poner la parte del recuento en negrita? Simplemente sería:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
En caso de que desee redefinir su "negrita" más adelante, sería muy fácil, no tendrá que revisar todos sus archivos YAML y cambiarlos, simplemente hágalo en un solo lugar.
Para obtener más información, eche un vistazo aquí:
https://github.com/tr8n/tr8n_rails_clientsdk
Divulgación: Soy el desarrollador y mantenedor del marco Tr8n y todas sus bibliotecas.
fuente
Sobre Redmine. Si copia las reglas del archivo de pluralización en config / locales / como plurals.rb y otro que no sea el mismo que el nombre del entorno local (ru.rb, pl.rb .. etc), estos no funcionan. Debe cambiar el nombre de las reglas del archivo a 'locale'.rb o cambiar el método en el archivo /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
y si tiene una redmine más antigua, agregue
module Implementation include ::I18n::Backend::Base **include ::I18n::Backend::Pluralization**
fuente