I18n:如何检查翻译键/值对是否缺失?

17

我正在使用Ruby on Rails 3.1.0和I18n gem。我想在运行时检查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有可能吗?如果可以,我该如何做?

顺便提一下:出于性能方面的考虑,运行时检查翻译键/值对是否存在是可取的吗?


1
这样的东西有用吗?https://dev59.com/NG855IYBdhLWcg3wpmHw - Jay
4个回答

23
您可以向 I18n.t 传递一个 :default 参数:
I18n.t :missing, :default => 'Not here'
# => 'Not here'

你可以在这里阅读更多相关信息


20

我刚刚有同样的问题,我想在翻译缺失的情况下计算出自动字符串。如果我使用 :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

18

我不知道如何在运行时做到这一点,但您可以使用rake来找出它。您需要为此创建自己的rake任务。这是一个示例:

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

将给定内容放入lib/tasks目录下的.rake文件中并执行:
rake i18n:missing_keys 

信息来源在这里,代码在github 这里


你的回答并没有达到我想要的效果,但还是谢谢你。等待另一个答案... - user12882
如果你做类似的事情,请注意由于不同的复数规则(因此不同的键),翻译键可能不完全匹配。在这里修复:https://gist.github.com/2994129(通过我的http://henrik.nyh.se/2012/07/rails-i18n-tips/) - Henrik N

0

如果您想将变量传递到消息中,例如这是测试错误消息{variable}

可以使用语言文件中的变量来实现此功能,如下所示。

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

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

你可以在这里找到更多的描述


谢谢您的回答,但那不是我要找的(请重新阅读问题)。 - user12882

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接