rails - 如何动态添加/覆盖对i18n yaml的措辞

时间:2009-12-03 14:01:56

标签: ruby-on-rails internationalization yaml

作为一个例子,我有一个默认的英语语言环境文件“en.yml”,内容为:

 en:
  messages: messages
  users: users

现在,有一位客户希望在其产品中将消息命名为讨论,但用户应保留用户。所以我想做的是创建“customer.en.yml”文件

en:
 messages: discussions

会覆盖默认的“消息”翻译,但会保留所有其他单词相同。我怎么能实现它?

因为如果我用:

加载en.yml
config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}')] 

然后加载customer.en.yml(APP_CONFIG ['customer_name']在之前定义)

config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'config', 'custom_locales',  APP_CONFIG['customer_name']+'.{rb|yml}')]

它只会覆盖我的“en”语言环境,“用户”翻译会消失,对吗?

4 个答案:

答案 0 :(得分:5)

使用i18n.fallbacks

我不确定这是什么时候添加到Rails中,但是在4.2.2中你可以这样做:

# application.rb
# If key is not found in a locale, we look in fallback
config.i18n.fallbacks = {
  "locale_1"    => "en",
  "locale_2"    => "en",
  "locale_3"    => "de",
}

如果您还设置config.action_view.raise_on_missing_translations = true(我在开发和测试中执行此操作),只有在区域设置后备中找不到密钥时才会引发此问题。

答案 1 :(得分:3)

它不应该覆盖您的“en”语言环境。翻译合并。简单的I18n后端store_translations调用merge_translations,如下所示:

# Deep merges the given translations hash with the existing translations
# for the given locale
def merge_translations(locale, data)
  locale = locale.to_sym
  translations[locale] ||= {}
  data = deep_symbolize_keys(data)

  # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
  merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
  translations[locale].merge!(data, &merger)
end

如您所见,只有您在后一个翻译yml文件中输入的密钥才会被覆盖。

答案 2 :(得分:1)

当我们编写pirate.yml翻译时,我想要类似的东西,但是我希望pirate.yml中没有定义的任何内容默认为我们在en.yml中的内容。

我写的内容可以在Github找到。

答案 3 :(得分:-1)

我认为你可能会混淆两种不同的东西。

i18n文件用于翻译。

如果您的客户端需要某个字段的特定名称,那么这不是翻译问题,而是功能。

换句话说,我认为你需要这样的东西:

 en:
   messages: messages
   users: users
   discussions: discussions

然后在其他地方添加特定功能,例如在您的视图中:

if(customer.needs_discussions?)
<%= t(:discussions) %>
else
<%= t(:messages) %>
end

或者,您可以向客户添加字符串属性,默认为“消息”。然后您的视图将如下所示:

<%= t(customer.messages_field_name) %>