Eu quero ser capaz de traduzir strings pluralizadas em i18n em trilhos. Uma string pode ser:
You have 2 kids
ou
You have 1 kid
Eu sei que posso usar o método auxiliar pluralize, mas quero incorporar isso nas traduções i18n para que eu não tenha que bagunçar minhas visões em nenhum momento no futuro. Eu li que :count
é de alguma forma usado em traduções para plural, mas não consigo encontrar nenhum recurso real sobre como ele é implementado.
Observe que eu sei que posso passar uma variável em uma string de tradução. Eu também tentei algo como:
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
O que funciona bem, mas tem um problema fundamental com a mesma ideia. Eu preciso especificar a string'kid'
no auxiliar pluralize. Não quero fazer isso porque levará a ver problemas no futuro. Em vez disso, quero manter tudo na tradução e nada na visualização.
Como eu posso fazer isso ?
"#{....}"
não são necessários no código acima.<%= t 'misc.kids', :kids_num => pluralize(1, t('kid')) %>
. Talvez isso não tenha funcionado em 2011 (!), Mas com certeza funciona agora no Rails 5.2.2Respostas:
Experimente isto:
en.yml
:en: misc: kids: zero: no kids one: 1 kid other: %{count} kids
Em uma vista:
You have <%= t('misc.kids', :count => 4) %>
Resposta atualizada para linguagens com pluralização múltipla (testado com Rails 3.0.7):
Arquivo
config/initializers/pluralization.rb
:require "i18n/backend/pluralization" I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
Arquivo
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`)
Arquivo
config/locales/en.yml
:en: kids: zero: en_zero one: en_one other: en_other
Arquivo
config/locales/ru.yml
:ru: kids: zero: ru_zero one: ru_one few: ru_few other: ru_other
Teste :
$ 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!
fonte
%{count}
funcionar, eu tive que usar aspas em todo o bloco, ou seja.one: "%{count} kid"
Espero que os programadores de Ruby on Rails que falam russo possam encontrar isso. Só quero compartilhar minha própria fórmula de pluralização russa muito precisa. É baseado nas especificações Unicode . Aqui está o conteúdo do
config/locales/plurals.rb
arquivo apenas, todo o resto deve ser feito da mesma forma que na resposta acima.{: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 } } } } }
Falantes nativos podem gostar de casos como
111
e121
. E aqui estão os resultados do teste:Obrigado pela resposta inicial!
fonte
config/locales/plurals.rb
vez deconfig/initializers/pluralization.rb
Primeiro, lembre-se de que o número de formas plurais depende do idioma , para o inglês existem duas, para o romeno existem 3 e para o árabe existem 6!.
Se você quiser usar as formas plurais de maneira adequada, terá que usar
gettext
.Para Ruby e rails, você deve verificar este http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
fonte
O Rails 3 lida com isso de maneira robusta com consideração CLDR e variável de interpolação de contagem. Consulte 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
fonte
Na verdade, existe uma alternativa para a abordagem complicada de i18n. A solução é chamada de Tr8n.
Seu código acima seria simplesmente:
<%= tr("You have {num || kid}", num: 1) %>
É isso aí. Não há necessidade de extrair suas chaves de seu código e mantê-los em pacotes de recursos, sem necessidade de implementar regras de pluralização para cada idioma. Tr8n vem com regras de contexto numérico para todos os idiomas. Ele também vem com regras de gênero, regras de lista e casos de linguagem.
A definição completa da chave de tradução acima seria realmente semelhante a esta:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
Mas, como queremos economizar espaço e tempo, num é mapeado automaticamente para regras numéricas e não há necessidade de fornecer todas as opções para os valores das regras. O Tr8n vem com pluralizadores e infletores que farão o trabalho para você na hora.
A tradução de sua chave em russo seria simplesmente:
"У вас есть {num || ребенок, ребенка, детей}"
A propósito, sua tradução seria imprecisa em idiomas que têm regras específicas de gênero. Por exemplo, em hebraico, você realmente teria que especificar pelo menos 2 traduções para o seu exemplo, já que "Você" seria diferente com base no sexo do usuário que está visualizando. Tr8n lida com isso muito bem. Aqui está uma transliteração das traduções hebraicas:
"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}}
Portanto, sua única chave em inglês, neste caso, precisa de 4 traduções. Todas as traduções são feitas no contexto - você não precisa quebrar a frase. O Tr8n tem um mecanismo para mapear uma chave para várias traduções com base no idioma e no contexto - tudo feito na hora.
Uma última coisa. E se você tivesse que deixar a contagem em negrito? Seria simplesmente:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
Apenas no caso de você querer redefinir seu "negrito" mais tarde - seria muito fácil - você não terá que passar por todos os seus arquivos YAML e alterá-los - basta fazê-lo em um só lugar.
Para saber mais, dê uma olhada aqui:
https://github.com/tr8n/tr8n_rails_clientsdk
Divulgação: Eu sou o desenvolvedor e mantenedor do framework Tr8n e de todas as suas bibliotecas.
fonte
Inglês
Simplesmente funciona fora da caixa
en.yml :
en: kid: one: '1 kid' other: '%{count} kids'
Uso (você pode pular I18n em um arquivo de visualização, é claro):
> I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids"
Russo (e outros idiomas com múltiplas formas plurais)
Instale o rails-18n gem e adicione traduções aos seus
.yml
arquivos como no exemplo :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: '' => "дети"
fonte
Sobre o Redmine. Se você copiar as regras do arquivo de pluralização em config / locales / as plurals.rb e outro diferente do nome do locale (ru.rb, pl.rb .. etc), isso não funcionará. Você deve renomear as regras de arquivo para 'locale'.rb ou alterar o método no arquivo /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
e se você tiver redmine mais antigo, adicione
module Implementation include ::I18n::Backend::Base **include ::I18n::Backend::Pluralization**
fonte