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

发布于 2024-08-13 04:13:37 字数 687 浏览 6 评论 0原文

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

 en:
  messages: messages
  users: users

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

en:
 messages: discussions

,它将覆盖默认的“messages”翻译,但会保持所有其他单词相同。我怎样才能实现它?

因为如果我用 : 加载 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”语言环境,并且“users”翻译将会消失,对吧?

as an example, i have a default english locale file "en.yml" with contents:

 en:
  messages: messages
  users: users

now, there is a customer which wants messages to be named discussions in his product, but users should remain users. so what i want to do is to create "customer.en.yml" file

en:
 messages: discussions

which would override the default "messages" translation, but would keep all the other words same. how can i achieve it?

because if i load en.yml with :

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

and afterwards load customer.en.yml (APP_CONFIG['customer_name'] is defined before) with

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

it will just overwrite my "en" locale, and "users" translation will disappear, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苄①跕圉湢 2024-08-20 04:13:38

使用 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 (我在开发中这样做,并且test),仅当在区域设置后备中找不到键时才会引发该错误。

Use i18n.fallbacks

I'm not sure when this was added to Rails, but in 4.2.2 you can do:

# 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",
}

If you also set config.action_view.raise_on_missing_translations = true (which I do in development and test), it will raise only if a key isn't found in the locale or the fallback.

静谧幽蓝 2024-08-20 04:13:38

它不应覆盖您的“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 文件中输入的键才会被覆盖。

It should not overwrite your "en" locale. Translations are merged. store_translations in the simple I18n backend calls merge_translations, which looks like this:

# 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

As you can see, only the keys you enter in the latter translation yml file will be overwritten.

谁的年少不轻狂 2024-08-20 04:13:38

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

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

I wanted something similar when we were writing a pirate.yml translation, but I wanted anything not defined in pirate.yml to default to what we had in en.yml.

What I wrote can be found on Github.

汐鸠 2024-08-20 04:13:38

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

i18n 文件用于翻译。

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

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

 en:
   messages: messages
   users: users
   discussions: discussions

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

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

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

<%= t(customer.messages_field_name) %>

I think you might be mixing up two different things.

The i18n file is for translations.

If you have a client that needs an specific name for some field, that is not a translation issue, but functionality.

In other words, I think you need something like this:

 en:
   messages: messages
   users: users
   discussions: discussions

And then add the specific functionality somewhere else, for example in your view:

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

Alternatively, you could add a string attribute to your customers, defaulting to 'messages'. Then your view would look like this:

<%= t(customer.messages_field_name) %>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文