i18n 복수화
레일에서 i18n의 복수 문자열을 번역하고 싶습니다. 문자열은 다음과 같을 수 있습니다.
You have 2 kids
또는
You have 1 kid
pluralize helper 메서드를 사용할 수 있다는 것을 알고 있지만 향후 어느 시점에서든 내 견해를 엉망으로 만들 필요가 없도록 i18n 번역에 이것을 포함하고 싶습니다. 나는 그것이 :count
어떻게 든 복수형 번역에 사용되는 것을 읽었 지만 그것이 어떻게 구현되는지에 대한 실제 자원을 찾을 수 없습니다.
번역 문자열에 변수를 전달할 수 있다는 것을 알고 있습니다. 나는 또한 다음과 같은 것을 시도했다.
<%= t 'misc.kids', :kids_num => pluralize(1, 'kid') %>
잘 작동하지만 동일한 아이디어의 근본적인 문제가 있습니다. 'kid'
복수형 도우미에 문자열을 지정해야합니다 . 그렇게하고 싶지 않다. 왜냐하면 미래에 문제를 보게 될 것이기 때문이다. 대신 번역에 모든 것을 유지하고보기에는 아무것도 남기지 않습니다.
어떻게 할 수 있습니까?
이 시도:
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!
러시아어를 사용하는 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 : 0 запросов / куриц / яблок
- 하나 : 1 запрос / курица / яблоко
- 소수 : 3 запроса / курицы / яблока
- 많은 : 5 запросов / куриц / яблок
- 하나 : 101 запрос / курица / яблоко
- 소수 : 102 запроса / курицы / яблока
- 많은 : 105 запросов / куриц / яблок
- 다수 : 111 запросов / куриц / яблок
- 다수 : 119 запросов / куриц / яблок
- 하나 : 121 запрос / курица / яблоко
- few: 122 запроса/курицы/яблока
- many: 125 запросов/куриц/яблок
Thanks for initial answer!
First, remember that number of plural forms depends on language, for English there are two, for Romanian there are 3 and for Arabic there are 6 !.
If you want to be able to properly use plural forms you have to use gettext
.
For Ruby and rails you should check this http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
Rails 3 handles this robustly with CLDR consideration and count interpolation variable. See 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
There is actually an alternative to the cumbersome i18n approach. The solution is called Tr8n.
Your above code would simply be:
<%= tr("You have {num || kid}", num: 1) %>
That's it. No need to extract your keys from your code and maintain them in resource bundles, no need to implement pluralization rules for each language. Tr8n comes with numeric context rules for all language. It also comes with gender rules, list rules and language cases.
The full definition of the above translation key would actually look like this:
<%= tr("You have {num:number || one: kid, other: kids}", num: 1) %>
But since we want to save space and time, num is automatically mapped to numeric rules and there is no need to provide all options for the rule values. Tr8n comes with pluralizers and inflectors that will do the work for you on the fly.
The translation for your key in Russian, would simply be:
"У вас есть {num || ребенок, ребенка, детей}"
By the way, your translation would be inaccurate in languages that have gender specific rules. For example, in Hebrew, you would actually have to specify at least 2 translations for your example, as "You" would be different based on the gender of the viewing user. Tr8n handles it very well. Here is a transliteration of Hebrew translations:
"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}}
So your single English key, in this case, needs 4 translations. All translations are done in context - you don't have to break the sentence. Tr8n has a mechanism to map one key to multiple translations based on the language and context - all done on the fly.
One last thing. What if you had to make the count part bold? It would simply be:
<%= tr("You have [bold: {num || kid}]", num: 1, bold: "<strong>{$0}</strong>") %>
Just in case you want to redefine your "bold" later - it would be very easy - you won't have to go through all your YAML files and change them - you just do it in one place.
To learn more, please take a look here:
https://github.com/tr8n/tr8n_rails_clientsdk
Disclosure: I am the developer and the maintainer of Tr8n framework and all its libraries.
About Redmine. If you copy pluralization file rules in config/locales/ as plurals.rb and other not same as locale name (ru.rb, pl.rb .. etc) these not work. You must rename file rules to 'locale'.rb or change method in 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
and if you have older redmine, add
module Implementation
include ::I18n::Backend::Base
**include ::I18n::Backend::Pluralization**
English
It just works out of the box
en.yml:
en:
kid:
one: '1 kid'
other: '%{count} kids'
Usage (you can skip I18n in a view file, of course):
> I18n.t :kid, count: 1
=> "1 kid"
> I18n.t :kid, count: 3
=> "3 kids"
Russian (and other languages with multiple plural forms)
Install rails-18n gem and add translations to your .yml
files as in the example:
ru.yml:
ru:
kid:
zero: 'нет детей'
one: '%{count} ребенок'
few: '%{count} ребенка'
many: '%{count} детей'
other: 'дети'
Usage:
> 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: ''
=> "дети"
참고URL : https://stackoverflow.com/questions/6166064/i18n-pluralization
'code' 카테고리의 다른 글
git 로그에 이동 된 파일의 기록이 표시되지 않는 이유는 무엇이며 어떻게해야합니까? (0) | 2020.10.05 |
---|---|
배열을 두 번 정렬하지 않고 Python / NumPy를 사용하여 배열의 항목 순위 지정 (0) | 2020.10.04 |
서버 측에서 WebSocket 메시지를 어떻게 보내고받을 수 있습니까? (0) | 2020.10.04 |
dataTables.js 라이브러리로 "N 개 항목 중 1 개 표시"를 숨기는 방법 (0) | 2020.10.04 |
C # 리플렉션 : 문자열에서 클래스 참조를 얻는 방법? (0) | 2020.10.04 |