wake-up-neo.com

pluralisierung

Ich möchte in Rails mehrere i18n-Strings übersetzen können. Eine Zeichenfolge kann sein:

You have 2 kids

oder

You have 1 kid

Ich weiß, dass ich die Hilfsmethode pluralize verwenden kann, aber ich möchte dies in i18n-Übersetzungen einbetten, damit ich mich zu keinem Zeitpunkt in der Zukunft mit meinen Ansichten auseinander setzen muss. Ich habe gelesen, dass :count irgendwie in Übersetzungen für Plural verwendet wird, aber ich kann keine echten Ressourcen finden, wie es implementiert wird.

Beachten Sie, dass ich weiß, dass ich eine Variable in einer Übersetzungszeichenfolge übergeben kann. Ich habe auch so etwas ausprobiert:

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

Was gut funktioniert, hat aber ein grundsätzliches Problem der gleichen Idee. Ich muss den String 'kid' im Helfer pluralize angeben. Ich möchte das nicht tun, weil dies in Zukunft Probleme verursachen wird. Stattdessen möchte ich alles in der Übersetzung und nichts in der Ansicht behalten.

Wie kann ich das machen ?

78
Spyros

Versuche dies:

en.yml:

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

In einer Ansicht:

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

Aktualisierte Antwort für Sprachen mit multipler Pluralisierung (getestet mit Rails 3.0.7):

Datei config/initializers/pluralization.rb:

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

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

Datei config/locales/en.yml:

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

Datei config/locales/ru.yml:

ru:
  kids:
    zero: ru_zero
    one: ru_one
    few: ru_few
    other: ru_other

Prüfung :

$ 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! 
163
Zabba

Ich hoffe, dass russischsprachige Programmierer von Ruby on Rails dies finden können. Ich möchte nur meine sehr genaue russische Pluralisierungsformel teilen. Es basiert auf Unicode Specs . Hier ist nur der Inhalt der config/locales/plurals.rb-Datei, alles andere sollte wie in der Antwort oben ausgeführt werden.

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

Muttersprachler können Fälle wie 111 und 121..__ genießen. Und hier die Testergebnisse:

  • null: 0 запросов/куриц/яблок
  • eins: 1 запрос/курица/яблоко
  • wenige: 3 запроса/курицы/яблока
  • viele: 5 запросов/куриц/яблок
  • eins: 101 запрос/курица/яблоко
  • wenige: 102 запроса/курицы/яблока
  • viele: 105 запросов/куриц/яблок
  • viele: 111 запросов/куриц/яблок
  • viele: 119 запросов/куриц/яблок
  • eins: 121 запрос/курица/яблоко
  • wenige: 122 запроса/курицы/яблока
  • viele: 125 запросов/куриц/яблок

Danke für die erste Antwort!

33
sashaegorov

Denken Sie zunächst daran, dass Anzahl der Pluralformen von der Sprache abhängt, für Englisch gibt es zwei, für Rumänisch gibt es 3 und für Arabisch gibt es 6!.

Wenn Sie mehrere Formen richtig verwenden möchten, müssen Sie gettext verwenden.

Für Ruby und Rails sollten Sie dies http://www.yotabanana.com/hiki/Ruby-gettext-howto-Rails.html überprüfen.

11
sorin

Rails 3 handhabt dies robust mit CLDR-Überlegungs- und Zählinterpolationsvariablen. Siehe 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
8
Luke W

Es gibt tatsächlich eine Alternative zum umständlichen i18n-Ansatz. Die Lösung heißt Tr8n. 

Ihr oben stehender Code wäre einfach:

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

Das ist es. Sie müssen Ihre Schlüssel nicht aus Ihrem Code extrahieren und in Ressourcenpaketen verwalten, keine Pluralisierungsregeln für jede Sprache implementieren. Tr8n enthält numerische Kontextregeln für alle Sprachen. Es enthält auch Geschlechtsregeln, Listenregeln und Sprachfälle.

Die vollständige Definition des obigen Übersetzungsschlüssels würde tatsächlich so aussehen:

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

Da wir jedoch Platz und Zeit sparen möchten, wird num automatisch numerischen Regeln zugeordnet, und es müssen nicht alle Optionen für die Regelwerte angegeben werden. Tr8n verfügt über Pluralizer und Inflektoren, die die Arbeit für Sie erledigen. 

Die Übersetzung für Ihren Schlüssel in Russisch lautet einfach:

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

Übrigens wäre Ihre Übersetzung in Sprachen mit geschlechtsspezifischen Regeln ungenau. In Hebräisch müssten Sie beispielsweise mindestens zwei Übersetzungen für Ihr Beispiel angeben, da "Sie" je nach Geschlecht des Betrachters unterschiedlich sein würde. Tr8n geht sehr gut damit um. Hier ist eine Transliteration von hebräischen Übersetzungen:

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

Ihr einziger englischer Schlüssel benötigt in diesem Fall also 4 Übersetzungen. Alle Übersetzungen werden im Kontext gemacht - Sie müssen den Satz nicht brechen. Tr8n verfügt über einen Mechanismus, um einen Schlüssel mehreren Übersetzungen zuzuordnen, die auf Sprache und Kontext basieren - und dies alles im Handumdrehen.

Eine letzte Sache. Was wäre, wenn Sie den Count-Teil fett machen müssten? Es wäre einfach:

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

Nur für den Fall, dass Sie später "fett" neu definieren möchten - es wäre sehr einfach - Sie müssen nicht alle Ihre YAML-Dateien durchgehen und sie ändern.

Um mehr zu erfahren, schauen Sie bitte hier:

https://github.com/tr8n/tr8n_Rails_clientsdk

Offenlegung: Ich bin Entwickler und Betreuer des Tr8n-Frameworks und aller seiner Bibliotheken.

2

Englisch

Es funktioniert einfach funktioniert aus der Box

de.yml:

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

Verwendung (Sie können I18n natürlich in einer Ansichtsdatei überspringen):

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

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

Russisch (und andere Sprachen mit mehreren Pluralformen)

Installiere Rails-18n gem und füge Übersetzungen zu deinen .yml-Dateien hinzu wie im example :

ru.yml:

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

Verwendungszweck:

> 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
installero

Über Redmine Wenn Sie Pluralisierungsdateiregeln in config/locales/als plurals.rb und andere als Locale-Name (ru.rb, pl.rb usw.) nicht kopieren, funktionieren diese nicht. Sie müssen die Dateiregel in "locale ".rb umbenennen oder die Methode in der Datei /lib/redmine/i18n.rb ändern

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

und wenn Sie ältere Redmine haben, fügen Sie hinzu

module Implementation
        include ::I18n::Backend::Base
        **include ::I18n::Backend::Pluralization**
0