2009-12-03 2 views
7

в качестве примера, у меня есть по умолчанию для английского языка файл с «en.yml» с содержанием:рельсов - как динамически добавлять/переопределение формулировки для i18n YAML

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}')] 

это будет просто перезапишите мой «ru» язык, и «пользовательский» перевод исчезнет, ​​верно?

ответ

3

Нельзя перезаписывать локализацию «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

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

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

+0

Ссылка Github больше не действительна! –

+0

Не действует? Хотя это очень старый проект, ссылка по-прежнему работает для меня. Вы получаете 404? –

+0

Точно, что страница не найдена, это то, что я получаю! –

-1

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

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

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

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

en: 
    messages: messages 
    users: users 
    discussions: discussions 

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

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

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

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

ну, тогда, если ему потребуется 200 изменений в формулировке, я должен написать 200 ifs и добавить 200 настроек клиента, а также для каждого другого клиента, использующего продукт по-своему. это значительно увеличило бы количество кода. и, если конкретный клиент уйдет, все эти ifs останутся в коде, в противном случае я просто удалю переопределение перевода. –

+0

Код был просто примером - я имел в виду, что вы не должны использовать i18n для этого. Я отредактировал свой комментарий с другими решениями. Если вы продолжаете думать об использовании i18n, подумайте о том, что произойдет, когда вам придется перевести ваше приложение на французский язык, например. – kikito

+1

У меня уже есть французский и английский i18n, а поверх них я загружаю переопределения клиентов. У меня есть locales/en.yml, locales/fr.yml, и, кроме того, я загружаю locales/customer.en.yml и locales/customer.fr.yml, если это необходимо. я сожалею, но я действительно думаю, что этот способ лучше подходит для простых формулировок –

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

Смежные вопросы