Saya ingin bisa menerjemahkan string yang jamak di i18n di rel. String bisa berupa:
You have 2 kids
atau
You have 1 kid
Saya tahu bahwa saya dapat menggunakan metode helper pluralize, tetapi saya ingin menyematkannya dalam terjemahan i18n sehingga saya tidak perlu mengacaukan pandangan saya kapan pun di masa mendatang. Saya membaca yang :count
entah bagaimana digunakan dalam terjemahan untuk jamak, tetapi saya tidak dapat menemukan sumber daya nyata tentang bagaimana penerapannya.
Perhatikan bahwa saya tahu bahwa saya dapat mengirimkan variabel dalam string terjemahan. Saya juga mencoba sesuatu seperti:
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
Yang berfungsi dengan baik, tetapi memiliki masalah mendasar dari ide yang sama. Saya perlu menentukan string 'kid'
dalam helper jamak. Saya tidak ingin melakukan itu karena itu akan mengarah pada masalah pandangan di masa depan. Sebaliknya saya ingin menyimpan semuanya dalam terjemahan dan tidak ada yang terlihat.
Bagaimana saya bisa melakukan itu?
"#{....}"
tidak diperlukan dalam kode di atas.<%= t 'misc.kids', :kids_num => pluralize(1, t('kid')) %>
. Mungkin ini tidak berhasil pada tahun 2011 (!) Tetapi sekarang pasti berhasil di Rails 5.2.2Jawaban:
Coba ini:
en.yml
:en: misc: kids: zero: no kids one: 1 kid other: %{count} kids
Dalam tampilan:
You have <%= t('misc.kids', :count => 4) %>
Jawaban yang diperbarui untuk bahasa dengan banyak pluralisasi (diuji dengan Rails 3.0.7):
File
config/initializers/pluralization.rb
:require "i18n/backend/pluralization" I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
File
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`)
File
config/locales/en.yml
:en: kids: zero: en_zero one: en_one other: en_other
File
config/locales/ru.yml
:ru: kids: zero: ru_zero one: ru_one few: ru_few other: ru_other
Tes :
$ 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!
sumber
%{count}
bekerja saya harus menggunakan tanda kutip di seluruh blok yaitu.one: "%{count} kid"
Saya berharap programmer Ruby on Rails yang berbahasa Rusia dapat menemukan ini. Hanya ingin berbagi rumus pluralisasi Rusia saya yang sangat tepat. Ini berdasarkan Spesifikasi Unicode . Berikut adalah isi
config/locales/plurals.rb
file saja, yang lainnya harus dilakukan seperti pada jawaban di atas.{: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 } } } } }
Penutur asli mungkin menyukai kasus seperti
111
dan121
. Dan berikut hasil tesnya:Terima kasih atas jawaban awal!
sumber
config/locales/plurals.rb
daripadaconfig/initializers/pluralization.rb
Pertama, ingat bahwa bentuk jamak tergantung pada bahasanya , untuk bahasa Inggris ada dua, untuk Rumania ada 3 dan untuk bahasa Arab ada 6!.
Jika Anda ingin dapat menggunakan bentuk jamak dengan benar, Anda harus menggunakan
gettext
.Untuk Ruby dan rails Anda harus memeriksa ini http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
sumber
Rails 3 menangani ini dengan kuat dengan pertimbangan CLDR dan menghitung variabel interpolasi. Lihat 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
sumber
Sebenarnya ada alternatif untuk pendekatan i18n yang rumit. Solusinya disebut Tr8n.
Kode Anda di atas hanya akan menjadi:
<%= tr("You have {num || kid}", num: 1) %>
Itu dia. Tidak perlu mengekstrak kunci dari kode Anda dan menyimpannya dalam paket sumber daya, tidak perlu menerapkan aturan pluralisasi untuk setiap bahasa. Tr8n hadir dengan aturan konteks numerik untuk semua bahasa. Itu juga dilengkapi dengan aturan gender, aturan daftar dan kasus bahasa.
Definisi lengkap dari kunci terjemahan di atas sebenarnya akan terlihat seperti ini:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
Tetapi karena kami ingin menghemat ruang dan waktu, num secara otomatis dipetakan ke aturan numerik dan tidak perlu menyediakan semua opsi untuk nilai aturan. Tr8n hadir dengan pluralizer dan inflektor yang akan bekerja untuk Anda dengan cepat.
Terjemahan untuk kunci Anda dalam bahasa Rusia, sederhananya adalah:
"У вас есть {num || ребенок, ребенка, детей}"
Omong-omong, terjemahan Anda mungkin tidak akurat dalam bahasa yang memiliki aturan khusus gender. Misalnya, dalam bahasa Ibrani, Anda sebenarnya harus menentukan setidaknya 2 terjemahan untuk contoh Anda, karena "Anda" akan berbeda berdasarkan jenis kelamin pengguna yang melihat. Tr8n menanganinya dengan sangat baik. Berikut adalah transliterasi dari terjemahan Ibrani:
"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}}
Jadi kunci bahasa Inggris tunggal Anda, dalam hal ini, membutuhkan 4 terjemahan. Semua terjemahan dilakukan dalam konteks - Anda tidak perlu memutuskan kalimat. Tr8n memiliki mekanisme untuk memetakan satu kunci ke beberapa terjemahan berdasarkan bahasa dan konteks - semuanya dilakukan dengan cepat.
Satu hal terakhir. Bagaimana jika Anda harus membuat bagian penghitungan menjadi tebal? Ini hanya akan menjadi:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
Untuk berjaga-jaga jika Anda ingin mendefinisikan kembali "tebal" Anda nanti - ini akan sangat mudah - Anda tidak perlu memeriksa semua file YAML Anda dan mengubahnya - Anda cukup melakukannya di satu tempat.
Untuk mempelajari lebih lanjut, silakan lihat di sini:
https://github.com/tr8n/tr8n_rails_clientsdk
Pengungkapan: Saya adalah pengembang dan pemelihara kerangka Tr8n dan semua perpustakaannya.
sumber
Inggris
Itu hanya bekerja di luar kotak
en.yml :
en: kid: one: '1 kid' other: '%{count} kids'
Penggunaan (Anda dapat melewati I18n dalam file tampilan, tentu saja):
> I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids"
Rusia (dan bahasa lain dengan berbagai bentuk jamak)
Instal permata rails-18n dan tambahkan terjemahan ke
.yml
file Anda seperti pada contoh :ru.yml :
ru: kid: zero: 'нет детей' one: '%{count} ребенок' few: '%{count} ребенка' many: '%{count} детей' other: 'дети'
Pemakaian:
> 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: '' => "дети"
sumber
Tentang Redmine. Jika Anda menyalin aturan file pluralisasi di config / locales / sebagai bentuk jamak.rb dan lainnya tidak sama dengan nama lokal (ru.rb, pl.rb .. dll) ini tidak berfungsi. Anda harus mengganti nama aturan file menjadi 'locale'.rb atau mengubah metode di file /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
dan jika Anda memiliki redmine lama, tambahkan
module Implementation include ::I18n::Backend::Base **include ::I18n::Backend::Pluralization**
sumber