Я хочу иметь возможность переводить строки с множественным числом в i18n в рельсы. Строка может быть:
You have 2 kids
или
You have 1 kid
Я знаю, что могу использовать вспомогательный метод множественного числа, но я хочу встроить его в переводы i18n, чтобы мне не приходилось портить свои представления в любой момент в будущем. Я читал, что :count
это как-то используется в переводах множественного числа, но я не могу найти реальных ресурсов о том, как это реализуется.
Обратите внимание: я знаю, что могу передать переменную в строке перевода. Я тоже пробовал что-то вроде:
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
Что отлично работает, но фундаментальная проблема та же идея. Мне нужно указать строку 'kid'
в помощнике множественного числа. Я не хочу этого делать, потому что это приведет к появлению проблем в будущем. Вместо этого я хочу сохранить все в переводе и ничего не видеть.
Как я могу это сделать ?
"#{....}"
в приведенном выше коде не нужны.<%= t 'misc.kids', :kids_num => pluralize(1, t('kid')) %>
. Возможно, это не сработало в 2011 году (!), Но теперь точно работает на Rails 5.2.2Ответы:
Попробуй это:
en.yml
:en: misc: kids: zero: no kids one: 1 kid other: %{count} kids
В представлении:
You have <%= t('misc.kids', :count => 4) %>
Обновленный ответ для языков с множественным множественным числом (проверено с Rails 3.0.7):
Файл
config/initializers/pluralization.rb
:require "i18n/backend/pluralization" I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
Файл
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`)
Файл
config/locales/en.yml
:en: kids: zero: en_zero one: en_one other: en_other
Файл
config/locales/ru.yml
:ru: kids: zero: ru_zero one: ru_one few: ru_few other: ru_other
Тест :
$ 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!
источник
%{count}
работать, мне пришлось использовать кавычки вокруг всего блока, т.е.one: "%{count} kid"
Я надеюсь, что русскоязычные программисты Ruby on Rails смогут это найти. Просто хочу поделиться своей собственной очень точной формулой плюрализации русского. Он основан на спецификациях Unicode . Вот только содержимое
config/locales/plurals.rb
файла, все остальное нужно делать так же, как в ответе выше.{: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 } } } } }
Носителям языка могут нравиться такие случаи, как
111
и121
. А вот результаты тестов:Спасибо за первоначальный ответ!
источник
config/locales/plurals.rb
а неconfig/initializers/pluralization.rb
Во-первых, помните, что количество форм множественного числа зависит от языка : для английского их два, для румынского - 3, а для арабского - 6!.
Если вы хотите иметь возможность правильно использовать формы множественного числа, вы должны использовать
gettext
.Для Ruby и rails вы должны проверить это http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
источник
Rails 3 надежно справляется с этим с учетом CLDR и переменной интерполяции подсчета. См. 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
источник
английский
Просто работает из коробки
en.yml :
en: kid: one: '1 kid' other: '%{count} kids'
Использование (вы, конечно, можете пропустить I18n в файле просмотра):
> I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids"
Русский (и другие языки с множественным числом форм)
Установите гем rails-18n и добавьте переводы в свои
.yml
файлы, как в примере :ru.yml :
ru: kid: zero: 'нет детей' one: '%{count} ребенок' few: '%{count} ребенка' many: '%{count} детей' other: 'дети'
Применение:
> 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: '' => "дети"
источник
На самом деле есть альтернатива громоздкому подходу i18n. Решение называется Tr8n.
Ваш код выше будет просто:
<%= tr("You have {num || kid}", num: 1) %>
Вот и все. Нет необходимости извлекать ключи из кода и сохранять их в пакетах ресурсов, нет необходимости реализовывать правила множественного числа для каждого языка. Tr8n поставляется с числовыми контекстными правилами для всех языков. Он также содержит гендерные правила, правила списков и языковые случаи.
Полное определение приведенного выше ключа перевода на самом деле будет выглядеть так:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
Но поскольку мы хотим сэкономить место и время, num автоматически сопоставляется с числовыми правилами, и нет необходимости предоставлять все параметры для значений правил. Tr8n поставляется с плюрализаторами и инфлекторами, которые сделают всю работу за вас на лету.
Перевод вашего ключа на русский язык будет просто:
"У вас есть {num || ребенок, ребенка, детей}"
Кстати, ваш перевод будет неточным на языках с гендерными правилами. Например, на иврите вам нужно будет указать как минимум 2 перевода для вашего примера, так как «Вы» будет отличаться в зависимости от пола просматривающего пользователя. Tr8n очень хорошо с этим справляется. Вот транслитерация переводов на иврит:
"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}}
Таким образом, для вашего единственного английского ключа в данном случае требуется 4 перевода. Все переводы выполняются в контексте - вам не нужно разбивать предложение. Tr8n имеет механизм сопоставления одного ключа с несколькими переводами в зависимости от языка и контекста - и все это делается на лету.
Последняя вещь. Что, если бы вам пришлось выделить счетную часть жирным шрифтом? Это было бы просто:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
На всякий случай, если вы захотите переопределить свой «жирный» позже - это будет очень просто - вам не придется просматривать все ваши файлы YAML и изменять их - вы просто делаете это в одном месте.
Чтобы узнать больше, посмотрите здесь:
https://github.com/tr8n/tr8n_rails_clientsdk
Раскрытие информации: я разработчик и сопровождающий фреймворка Tr8n и всех его библиотек.
источник
О Redmine. Если вы скопируете правила файла множественного числа в config / locales / как plurals.rb и другие, отличные от имени локали (ru.rb, pl.rb .. и т. Д.), Они не будут работать. Вы должны переименовать правила файла в 'locale'.rb или изменить метод в файле /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
а если у вас более старая версия Redmine, добавьте
module Implementation include ::I18n::Backend::Base **include ::I18n::Backend::Pluralization**
источник