16

Я использую Ruby on Rails 3.1.0 и I18n gem. Я (внедряю плагин и) Я бы хотел проверить во время выполнения, если в I18n отсутствуют пары ключей/значений трансляции и, если да, использовать пользовательскую строку. То есть, у меня есть:I18n: Как проверить, отсутствуют ли пары ключей/значений трансляции?

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

Если в файле .yml не существует следующий код

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

Я хотел бы использовать This is the test error message 2. Возможно ли это? Если да, то как я могу это сделать?

BTW: Из соображений производительности, это целесообразно проверить во время выполнения если ключевые перевод пар/значение присутствует?

+1

Возможно, что-то подобное? http://stackoverflow.com/questions/4223806/how-to-use-rails-i18n-fallback-features – illiptic

ответ

18

У меня был такой же вопрос, и я хочу вычислить автоматическую строку в случае отсутствия перевода. Если я использую параметр :default, я должен каждый раз вычислять автоматическую строку, даже когда перевод не пропущен. Поэтому я искал другое решение.

Вы можете добавить опцию :raise => true или использовать I18n.translate! вместо I18n.translate. Если перевод не найден, возникает исключение.

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

Я не знаю, как это происходит во время выполнения, но вы можете использовать рейк, чтобы узнать это. Для этого у вас будет своя собственная задача рейка. Вот один:

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 

поместить данное в файле .rake в вашем Lib каталоге/задачи и выполнить:

rake i18n:missing_keys 

источник Информация here и код на GitHub here.

+0

Ваш ответ не выполняет то, что я ищу, но в любом случае спасибо. Ожидание другого ответа ... – user12882

+0

Если вы сделаете что-то подобное, обратите внимание, что ключи перевода могут не совпадать точно из-за разных правил плюрализации (и, следовательно, разных ключей). Исправлено: https://gist.github.com/2994129 (через мой http: //henrik.nyh.se/2012/07/rails-i18n-tips /) –

0

Если вы хотите передать переменную в сообщение как This is the test error message {variable}

Это возможно с помощью переменной в языковом файле, как показано ниже.

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

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

Дополнительное описание вы можете find here.

+0

Благодарим вас за ответ, но это не то, что я ищу (перечитайте вопрос, пожалуйста). – user12882

21

Вы можете передать: по умолчанию параметр для I18n.t:

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

Вы можете прочитать больше об этом here.

Смежные вопросы