плюрализация как i18n
Я хочу иметь возможность переводить несколько строк в i18n в rails. Строка может быть :
You have 2 kids
или
You have 1 kid
Я знаю, что могу использовать вспомогательный метод pluralize, но я хочу встроить его в переводы i18n, чтобы мне не пришлось путаться с моими взглядами в любой момент в будущем. Я читал это :count как-то используется в переводах для множественного числа, но я не могу найти никаких реальных ресурсов о том, как он реализуется.
обратите внимание, что я знаю, что я могу передайте переменную в строке перевода. Я тоже попробовал что-то вроде :
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
который отлично работает, но имеет фундаментальную проблему той же идеи. Мне нужно указать строку 'kid' в помощнике множественного числа. Я не хочу этого делать, потому что это приведет к возникновению проблем в будущем. Вместо этого я хочу сохранить все в переводе и ничего в представлении.
как я могу это сделать ?
7 ответов:
попробуйте это:
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):
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_otherFile
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!
Я надеюсь, что русскоязычные программисты Ruby on Rails смогут найти это. Просто хочу поделиться своей очень точной русской формулой плюрализации. Он основан на Спецификации Юникода. Вот содержание
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. И вот результаты теста:
- ноль: 0 запросов/куриц/яблок
- одна: 1 запрос/курица/яблоко
- немногие: 3 запроса/курицы/яблока
- многие: 5 запросов/куриц/яблок
- один: 101 запрос / курица / яблоко
- немногие: 102 запроса/курицы/яблока
- многие: 105 запросов/куриц/яблок
- многие: 111 запросов/куриц/яблок
- многие: 119 запросов/куриц/яблок
- один: 121 запрос/курица/яблоко
- немногие: 122 запроса/курицы/яблока
- много: 125 запросов/куриц/яблок
Спасибо за первоначальный ответ!
во-первых, помните, что количество форм множественного числа зависит от языка, для английского есть два, для румынского есть 3 и для арабского есть 6 !.
Если вы хотите правильно использовать формы множественного числа, вы должны использовать
gettext.для Ruby и rails вы должны проверить это http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
Rails 3 обрабатывает это надежно с учетом CLDR и переменной интерполяции count. См.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
на самом деле существует альтернатива громоздкому подходу i18n. Решение называется Tr8n.
ваш код выше будет просто:
<%= tr("You have {num || kid}", num: 1) %>вот именно. Нет необходимости извлекать ключи из кода и поддерживать их в пакетах ресурсов, нет необходимости реализовывать правила плюрализации для каждого языка. Tr8n поставляется с числовыми правилами контекста для всех языков. Он также поставляется с гендерными правилами, правилами списка и языковыми случаями.
полное определение выше ключ перевод на самом деле будет выглядеть так:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>но поскольку мы хотим сэкономить пространство и время, num автоматически сопоставляется с числовыми правилами, и нет необходимости предоставлять все параметры для значений правил. Tr8n поставляется с pluralizers и инфлекторы, который будет делать работу за вас на лету.
перевод для вашего ключа на русском языке, будет просто:
"У вас есть {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>{}</strong>") %>на всякий случай вы хотите переопределить свой "жирный" позже - это было бы очень легко - вам не придется проходить через все ваши файлы YAML и изменять их - вы просто делаете это в одном месте.
чтобы узнать больше, пожалуйста, взгляните здесь:
https://github.com/tr8n/tr8n_rails_clientsdk
раскрытие информации: я являюсь разработчиком и сопровождающим tr8n framework и всех его библиотек.
английский язык
это просто работает из окна
ванной.в формате YML:
en: kid: one: '1 kid' other: '%{count} kids'использование (Вы можете пропустить I18n в файле представления, конечно):
> I18n.t :kid, count: 1 => "1 kid" > I18n.t :kid, count: 3 => "3 kids"русский (и другие языки с несколькими формами множественного числа)
установить рельсы-18n gem и добавить переводы на ваш
.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: '' => "дети"
О Redmine. Если вы копируете правила файла плюрализации в config / locales / as plurals.rb и другие не совпадают с именем локали (ru.РБ, пл.рубидий.. etc) эти не работают. Вы должны переименовать правила файлов в 'locale'.или способ изменения РБ в файле /lib/Redmine в/с названием i18n.
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**
Comments