English 中文(简体)
rails - how to dynamically add/override wording to i18n yaml
原标题:

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?

最佳回答

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.

问题回答

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.

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.

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) %>




相关问题
How does gettext handle dynamic content?

In php (or maybe gettext in general), what does gettext do when it sees a variable to dynamic content? I have 2 cases in mind. 1) Let s say I have <?=$user1?> poked John <?=$user2?>. ...

Explain the Need for Mutexes in Locales, Please

Reading the question Why doesn’t C++ STL support atoi(const string& ) like functions?, I encountered a comment which warned that GCC (at least) has a bug that can slow down multi-threaded ...

How does Vistalizer work

How does Vistalizer manage to override the language limit in Windows Vista Home edition. Which api s does it use to allow installation of Multiple language packages.

Localized exceptions (within a Struts2 app)

I am developing a Struts 2 application with support for multiple languages. If one of the domain objects needs to throw an exception, how can it do so in such a way that the error message is no ...

Rails Globalize plugin help

Has anyone gotten the Globalize plugin to work Rails 2.3.2 or later? If so, could you direct me to some useful info?

热门标签