views:

421

answers:

3

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?

+1  A: 

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.

Clinton R. Nixon
A: 

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 me found here: http://github.com/amiel/i18n_with_default

Amiel Martin
A: 

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) %>
egarcia
well,then if he needs 200 changes in wording, i have to write 200 ifs and add 200 customer settings, and same for each other customer using product his own way. this would heavily increase amount of code. and, if the specific customer leaves at, all those ifs would stay in the code, while otherwise i simply delete translation override.
Pavel K.
The code was just an example - what I meant is that you shouldn't be using i18n for that. I've edited my comment with other solutions. If you continue thinking about using i18n, think about what will happen when you have to translate your application to french, for instance.
egarcia
i already have french and english i18n, and on top of them i load customer overrides. i have locales/en.yml, locales/fr.yml and on top of them i load locales/customer.en.yml and locales/customer.fr.yml, if needed. i am sorry, but i really think that this way is way better for simple wording customizations
Pavel K.