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

时间:2021-09-17 20:38:43

I am using Ruby on Rails 3.1.0 and the I18n gem. I (am implementing a plugin and) I would like to check at runtime if the I18n is missing a translation key/value pairs and, if so, to use a custom string. That is, I have:

我正在使用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'
  )
}

If in the .yml file there is not the following code

如果在.yml文件中没有以下代码

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

I would like to use the This is the test error message 2. Is it possible? If so, how can I make that?

我想使用这是测试错误消息2.是否可能?如果是这样,我该怎么做?

BTW: For performance reasons, is it advisable to check at runtime if the translation key/value pairs is present?

顺便说一句:出于性能原因,建议在运行时检查转换键/值对是否存在?

4 个解决方案

#1


19  

I just had the same question and I want to compute an automatic string in case the translation is missing. If I use the :default option I have to compute the automatic string every time even when the translation is not missing. So I searched for another solution.

我只是有同样的问题,我想计算一个自动字符串,以防翻译丢失。如果我使用:default选项,我每次都要计算自动字符串,即使翻译没有丢失。所以我搜索了另一个解决方案。

You can add the option :raise => true or use I18n.translate! instead of I18n.translate. If no translation can be found an exception is raised.

您可以添加选项: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

#2


23  

You could pass a :default parameter to I18n.t:

您可以将:default参数传递给I18n.t:

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

You can read more about it here.

你可以在这里读更多关于它的内容。

#3


16  

I don't know how to this at runtime but you can use rake to find it out. You'll have create your own rake task for that. Here's one:

我不知道如何在运行时,但你可以使用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

put the given in a .rake file in your lib/tasks directory and execute:

将给定的.rake文件放在lib / tasks目录中并执行:

rake i18n:missing_keys 

Information source is here and code on github here.

信息源在这里,github上的代码在这里。

#4


0  

If you wish to pass variable to the message like This is the test error message {variable}

如果您希望将变量传递给消息,例如这是测试错误消息{variable}

This is possible using variable in language file like below.

这可以使用如下语言文件中的变量。

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

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

More description you can find here.

您可以在这里找到更多描述。

#1


19  

I just had the same question and I want to compute an automatic string in case the translation is missing. If I use the :default option I have to compute the automatic string every time even when the translation is not missing. So I searched for another solution.

我只是有同样的问题,我想计算一个自动字符串,以防翻译丢失。如果我使用:default选项,我每次都要计算自动字符串,即使翻译没有丢失。所以我搜索了另一个解决方案。

You can add the option :raise => true or use I18n.translate! instead of I18n.translate. If no translation can be found an exception is raised.

您可以添加选项: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

#2


23  

You could pass a :default parameter to I18n.t:

您可以将:default参数传递给I18n.t:

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

You can read more about it here.

你可以在这里读更多关于它的内容。

#3


16  

I don't know how to this at runtime but you can use rake to find it out. You'll have create your own rake task for that. Here's one:

我不知道如何在运行时,但你可以使用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

put the given in a .rake file in your lib/tasks directory and execute:

将给定的.rake文件放在lib / tasks目录中并执行:

rake i18n:missing_keys 

Information source is here and code on github here.

信息源在这里,github上的代码在这里。

#4


0  

If you wish to pass variable to the message like This is the test error message {variable}

如果您希望将变量传递给消息,例如这是测试错误消息{variable}

This is possible using variable in language file like below.

这可以使用如下语言文件中的变量。

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

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

More description you can find here.

您可以在这里找到更多描述。