rails - как динамически добавить / переопределить формулировку для i18n yaml - PullRequest
7 голосов
/ 03 декабря 2009

в качестве примера, у меня есть файл английской локали по умолчанию "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" локаль, и перевод "users" исчезнет, ​​верно?

Ответы [ 4 ]

5 голосов
/ 27 августа 2015

Использовать 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 (что я делаю при разработке и тестировании), он будет повышаться только в том случае, если ключ не найден в локали или откат.

3 голосов
/ 03 декабря 2009

Он не должен перезаписывать вашу "en" локаль. Переводы объединены. store_translations в простом бэкэнде I18n вызывает 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-файле перевода, будут перезаписаны.

1 голос
/ 03 декабря 2009

Я хотел что-то похожее, когда мы писали перевод pirate.yml, но я хотел, чтобы по умолчанию все, что не определено в pirate.yml, соответствовало тому, что было в en.yml.

То, что я написал, можно найти на Github .

0 голосов
/ 04 декабря 2009

Я думаю, вы можете смешивать две разные вещи.

Файл i18n предназначен для переводов.

Если у вас есть клиент, которому нужно определенное имя для какого-либо поля, это не проблема перевода, а функциональность.

Другими словами, я думаю, вам нужно что-то вроде этого:

 en:
   messages: messages
   users: users
   discussions: discussions

А затем добавьте конкретную функциональность где-нибудь еще, например, на ваш взгляд:

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

В качестве альтернативы, вы можете добавить строковый атрибут для ваших клиентов, по умолчанию «сообщения». Тогда ваш взгляд будет выглядеть так:

<%= t(customer.messages_field_name) %>
...