i18n Çoğullaştırma


89

İ18n'deki çoğullaştırılmış dizeleri raylarda çevirebilmek istiyorum. Bir dize şunlar olabilir:

You have 2 kids

veya

You have 1 kid

Pluralize helper yöntemini kullanabileceğimi biliyorum, ancak bunu i18n çevirilerine gömmek istiyorum, böylece gelecekte herhangi bir noktada görüşlerimi karıştırmak zorunda kalmayayım. :countÇoğul çevirilerde bir şekilde kullanıldığını okudum , ancak nasıl uygulandığına dair gerçek bir kaynak bulamıyorum.

Bir değişkeni bir çeviri dizesinde geçirebileceğimi bildiğime dikkat edin. Ayrıca şöyle bir şey denedim:

<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>

İyi çalışıyor, ancak aynı fikirle ilgili temel bir sorunu var. 'kid'Çoğullama yardımcısında dizeyi belirtmem gerekiyor . Bunu yapmak istemiyorum çünkü gelecekte sorunları görmeye yol açacak. Bunun yerine, her şeyi çeviride ve hiçbir şeyi görünümde tutmak istiyorum.

Bunu nasıl yapabilirim ?


2
"#{....}"Yukarıdaki kodda "interpolator" ve alıntıların gerekli olmadığını unutmayın.
Zabba

1
yanlış bir yaklaşımınız var çünkü diğer diller için çoğulların İngilizce'deki gibi çalıştığını varsayıyorsunuz. Doğru bir yaklaşım için cevabıma bakın .
sorin

Sorin, cevabın için teşekkürler, sadece bunun için gettext kullanmak istemiyorum. Zabba'nın çözümünün i18n ile ihtiyaçlarım için harika olduğunu düşünüyorum.
Spyros

Rails 3, CLDR ve 'count' enterpolasyon değişkenini kullanarak daha sağlam bir şekilde işler: guides.rubyonrails.org/i18n.html#pluralization
Luke W

Yıllar sonra, ama aynı zamanda dize 'çocuk' üzerine bir çeviri kullanabilirsiniz - Eğer varsa o kadar: <%= t 'misc.kids', :kids_num => pluralize(1, t('kid')) %>. Belki bu 2011'de işe yaramadı (!) Ama şimdi kesinlikle Rails 5.2.2'de
Jarvis Johnson

Yanıtlar:


176

Bunu dene:

en.yml :

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

Bir görünümde:

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

Çoklu çoğullama içeren diller için güncellenmiş yanıt (Rails 3.0.7 ile test edilmiştir):

Dosya config/initializers/pluralization.rb :

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

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

Dosya config/locales/en.yml :

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

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

Üzgünüm ama bu pek çok dilde çalışmıyor. Çoğullaştırma gerçekten karmaşık, bkz. Translate.sourceforge.net/wiki/l10n/pluralforms Bu nedenle, cevabımın daha uygun olduğunu düşünüyorum.
sorin

1
@sorin, cevabımı çoklu çoğullaştırma kurallarını kullanacak şekilde güncelledi.
Zabba

5
Sorun değil, ama şimdi çoğullaştırma sözlüğünü korumak için yeni bir tam zamanlı işin var !.
sorin

Bu harika! Yapmak için %{count}ben bütün blok yani etrafında tırnak kullanmak zorunda kaldı çalışmak. one: "%{count} kid"
firedev

1
@ThePablick, evet, '/ initializer' dizinindeki dosyalar yalnızca bir kez yüklenir - http sunucusu başlangıcında.
Zabba

37

Umarım Rusça konuşan Ruby on Rails programcıları bunu bulabilir. Kendi çok hassas Rusça çoğullaştırma formülümü paylaşmak istiyorum. Unicode Özelliklerine dayanmaktadır . İşte config/locales/plurals.rbsadece dosyanın içeriği , diğer her şey yukarıdaki cevapta olduğu gibi yapılmalıdır.

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

Anadili İngilizce olan kişiler 111ve gibi durumların tadını çıkarabilir 121. Ve işte test sonuçları:

  • sıfır: 0 запросов / куриц / яблок
  • one: 1 запрос / курица / яблоко
  • birkaç: 3 запроса / курицы / яблока
  • çok: 5 запросов / куриц / яблок
  • one: 101 запрос / курица / яблоко
  • birkaç: 102 запроса / курицы / яблока
  • çok: 105 запросов / куриц / яблок
  • çok: 111 запросов / куриц / яблок
  • çok: 119 запросов / куриц / яблок
  • one: 121 запрос / курица / яблоко
  • birkaç: 122 запроса / курицы / яблока
  • çok: 125 запросов / куриц / яблок

İlk cevabınız için teşekkürler!


1
Bahsettiğiniz diğer cevap, bunu farklı bir dosyaya yerleştirdi. Yani bu yaklaşım ile içerik gitmeli config/locales/plurals.rbyerineconfig/initializers/pluralization.rb
silverdr

@silverdr Cevapta dosya adını düzelttim. Bahşiş için teşekkürler!
sashaegorov

11

Öncelikle, çoğul biçimlerin sayısının dile bağlı olduğunu unutmayın; İngilizce için iki, Romence için 3 ve Arapça için 6!

Çoğul formları doğru bir şekilde kullanabilmek istiyorsanız kullanmanız gerekir gettext.

Ruby ve raylar için bu http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html adresini kontrol etmelisiniz.


4
Sorin, düşündüğüm de buydu ama bu CLDR formatını ( unicode.org/repos/cldr-tmp/trunk/diff/supplemental/… ) takip ederek çözülmüş gibi görünüyor . Yanlış mıyım?
Nikos D

Ayrıca 1., 2., 3., 4., 11., 12. ve 13. ancak 21., 22., 23. ve benzeri var.
gnasher729


5

Aslında hantal i18n yaklaşımına bir alternatif var. Çözüme Tr8n denir.

Yukarıdaki kodunuz basitçe şöyle olacaktır:

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

Bu kadar. Anahtarlarınızı kodunuzdan çıkarmanıza ve bunları kaynak paketlerinde tutmanıza gerek yoktur, her dil için çoğullaştırma kuralları uygulamaya gerek yoktur. Tr8n, tüm diller için sayısal bağlam kuralları ile birlikte gelir. Aynı zamanda cinsiyet kuralları, liste kuralları ve dil durumları ile birlikte gelir.

Yukarıdaki çeviri anahtarının tam tanımı aslında şöyle görünecektir:

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

Ancak yer ve zamandan tasarruf etmek istediğimizden, num otomatik olarak sayısal kurallara eşlenir ve kural değerleri için tüm seçenekleri sağlamaya gerek yoktur. Tr8n, işi sizin için anında yapacak çoğullayıcılar ve saptırıcılar ile birlikte gelir.

Anahtarınızın Rusça çevirisi basitçe şöyle olacaktır:

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

Bu arada, cinsiyete özgü kuralları olan dillerde çeviriniz yanlış olacaktır. Örneğin, İbranice'de, aslında örneğiniz için en az 2 çeviri belirtmeniz gerekir, çünkü "Siz", görüntüleyen kullanıcının cinsiyetine göre farklı olacaktır. Tr8n bunu çok iyi idare ediyor. İşte İbranice çevirilerin bir çevirisi:

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

Yani bu durumda tek İngilizce anahtarınız 4 çeviriye ihtiyaç duyar. Tüm çeviriler bağlam içinde yapılır - cümleyi kırmak zorunda değilsin. Tr8n, dil ve bağlama dayalı olarak bir anahtarı birden çok çeviriye eşlemek için bir mekanizmaya sahiptir - hepsi anında yapılır.

Son bir şey. Ya sayım kısmını kalın yapmak zorunda olsaydın? Basitçe şöyle olurdu:

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

Sadece "kalın" ifadenizi daha sonra yeniden tanımlamak istemeniz durumunda - bu çok kolay olacaktır - tüm YAML dosyalarınızı gözden geçirmek ve değiştirmek zorunda kalmayacaksınız - sadece tek bir yerde yaparsınız.

Daha fazla bilgi edinmek için lütfen buraya bir göz atın:

https://github.com/tr8n/tr8n_rails_clientsdk

Açıklama: Tr8n çerçevesinin ve tüm kitaplıklarının geliştiricisi ve bakımcısıyım.


1
Keşke olumsuz oyların ne için olduğunu bilseydim, cevap iyi görünüyor.
doug65536

5

ingilizce

Bu sadece çalışır kutudan

en.yml :

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

Kullanım (elbette bir görünüm dosyasında I18n'yi atlayabilirsiniz):

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

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

Rusça (ve çoklu çoğul biçimli diğer diller)

Rails-18n gem'i kurun .ymlve örnekteki gibi dosyalarınıza çeviriler ekleyin :

ru.yml :

ru:
  kid:
    zero: 'нет детей'
    one: '%{count} ребенок'
    few: '%{count} ребенка'
    many: '%{count} детей'
    other: 'дети'

Kullanım:

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

0

Redmine hakkında. Çoğullaştırma dosyası kurallarını config / locales / plurals.rb olarak kopyalarsanız ve diğer adıyla aynı olmayan (ru.rb, pl.rb .. vb.) Bunlar çalışmaz. Dosya kurallarını 'locale'.rb olarak yeniden adlandırmalı veya /lib/redmine/i18n.rb dosyasındaki yöntemi değiştirmelisiniz.

def init_translations(locale)
  locale = locale.to_s
  paths = ::I18n.load_path.select {|path| File.basename(path, '.*') == locale}
  load_translations(paths)
  translations[locale] ||= {}
end

ve daha eski redmine sahipseniz ekleyin

module Implementation
        include ::I18n::Backend::Base
        **include ::I18n::Backend::Pluralization**
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.