16

Sto usando Ruby on Rails 3.1.0 e I18n gem. Io (sto implementando un plugin e) Vorrei verificare a runtime se I18n manca una chiave di traduzione/coppie di valori e, in tal caso, usare una stringa personalizzata. Cioè, ho:I18n: come verificare se mancano coppie chiave/valore di traduzione?

validates :link_url, 
    :format  => { 
    :with => REGEX, 
    :message => I18n.t(
     'custom_invalid_format', 
     :scope => 'activerecord.errors.messages' 
) 
} 

Se nel file .yml non è il seguente codice

activerecord: 
    errors: 
    messages: 
     custom_invalid_format: This is the test error message 1 

Vorrei utilizzare il This is the test error message 2. È possibile? Se è così, come posso farlo?

proposito: Per motivi di prestazioni, è opportuno controllare a runtime se la chiave traduzione/valore c'è?

+1

Sarebbe qualcosa di utile? http://stackoverflow.com/questions/4223806/how-to-use-rails-i18n-fallback-features – illiptic

risposta

18

Ho appena avuto la stessa domanda e voglio calcolare una stringa automatica nel caso in cui la traduzione sia mancante. Se utilizzo l'opzione :default, devo calcolare ogni volta la stringa automatica anche quando la traduzione non è mancante. Così ho cercato un'altra soluzione.

È possibile aggiungere l'opzione :raise => true oppure utilizzare I18n.translate! anziché I18n.translate. Se non è possibile trovare alcuna traduzione, viene sollevata un'eccezione.

begin 
    I18n.translate!('this.key.should.be.translated', :raise => true) 
rescue I18n::MissingTranslationData 
    do_some_resource_eating_text_generation_here 
end 
16

Non so come farlo in fase di esecuzione ma è possibile utilizzare il rake per scoprirlo. Avrai creato il tuo compito di rake per quello. Eccone uno:

namespace :i18n do 
    desc "Find and list translation keys that do not exist in all locales" 
    task :missing_keys => :environment do 

    def collect_keys(scope, translations) 
     full_keys = [] 
     translations.to_a.each do |key, translations| 
     new_scope = scope.dup << key 
     if translations.is_a?(Hash) 
      full_keys += collect_keys(new_scope, translations) 
     else 
      full_keys << new_scope.join('.') 
     end 
     end 
     return full_keys 
    end 

    # Make sure we've loaded the translations 
    I18n.backend.send(:init_translations) 
    puts "#{I18n.available_locales.size} #{I18n.available_locales.size == 1 ? 'locale' : 'locales'} available: #{I18n.available_locales.to_sentence}" 

    # Get all keys from all locales 
    all_keys = I18n.backend.send(:translations).collect do |check_locale, translations| 
     collect_keys([], translations).sort 
    end.flatten.uniq 
    puts "#{all_keys.size} #{all_keys.size == 1 ? 'unique key' : 'unique keys'} found." 

    missing_keys = {} 
    all_keys.each do |key| 

     I18n.available_locales.each do |locale| 
     I18n.locale = locale 
     begin 
      result = I18n.translate(key, :raise => true) 
     rescue I18n::MissingInterpolationArgument 
      # noop 
     rescue I18n::MissingTranslationData 
      if missing_keys[key] 
      missing_keys[key] << locale 
      else 
      missing_keys[key] = [locale] 
      end 
     end 
     end 
    end 
    puts "#{missing_keys.size} #{missing_keys.size == 1 ? 'key is missing' : 'keys are missing'} from one or more locales:" 
    missing_keys.keys.sort.each do |key| 
     puts "'#{key}': Missing from #{missing_keys[key].join(', ')}" 
    end 
    end 
end 

mettere il dato in un file .rake nella directory lib/task ed esecuzione:

rake i18n:missing_keys 

fonte delle informazioni è here e il codice su GitHub here.

+0

La tua risposta non non realizzare quello che sto cercando, ma grazie lo stesso. In attesa di un'altra risposta ... – user12882

+0

Se si fa qualcosa di simile, si noti che le chiavi di traduzione potrebbero non corrispondere esattamente a causa di diverse regole di pluralizzazione (e quindi di chiavi diverse). Risolto qui: https://gist.github.com/2994129 (tramite il mio http: //henrik.nyh.se/2012/07/rails-i18n-tips /) –

0

Se si desidera passare variabile al messaggio come This is the test error message {variable}

Questo è possibile utilizzando variabile nel file di linguaggio come qui di seguito.

# app/views/home/index.html.erb 
<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %> 

# config/locales/en.yml 
    en: 
    greet_username: "%{message}, %{user}!" 

Più descrizione Puoi find here.

+0

Grazie per la risposta, ma non è quello che sto cercando (rileggi la domanda, per favore). – user12882

21

si poteva passare un: parametro predefinito per I18n.t:

I18n.t :missing, :default => 'Not here' 
# => 'Not here' 

Si può leggere di più su di esso here.