
i18n Rails: полное руководство по интернационализации Ruby on Rails
От первого файла локали до рабочей среды: настройте Rails I18n, используйте вспомогательную функцию t(), обработайте формы множественного числа CLDR, исправьте распространённые ошибки и добавьте умные цепочки резервных локалей.
Разобраться в архитектуре Rails I18n
Rails поставляется со встроенным пакетом I18n. Файлы перевода находятся в config/locales/ в формате YAML по умолчанию или Ruby. Фреймворк предоставляет вспомогательную функцию t(), псевдоним I18n.translate, в представлениях, контроллерах, моделях и почтовых службах. Rails I18n намеренно прост и сразу обрабатывает базовый перевод, интерполяцию и формы множественного числа.
# Rails includes i18n out of the box via the i18n gem
# config/application.rb
module MyApp
class Application < Rails::Application
# Default locale
config.i18n.default_locale = :en
# Available locales
config.i18n.available_locales = [:en, :de, :ja, :es, :fr, :'pt-BR']
# Fallback to default locale when translation is missing
config.i18n.fallbacks = true
# Load translations from nested directories
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
end
end# config/routes.rb
Rails.application.routes.draw do
scope "/:locale", locale: /en|de|ja|es|fr|pt-BR/ do
root "home#index"
resources :products
end
root "home#index"
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
around_action :switch_locale
private
def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
def default_url_options
{ locale: I18n.locale }
end
endНастроить параметры локали
Задайте default_locale, available_locales и резервное поведение в config/application.rb или инициализаторе. Настройте определение локали в ApplicationController с помощью before_action, чтобы получать её из URL, сеанса, cookie или заголовка Accept-Language.
# config/locales/en.yml
en:
nav:
home: "Home"
about: "About"
settings: "Settings"
greeting: "Hello, %{name}!"
cart:
item_count:
one: "%{count} item"
other: "%{count} items"
# config/locales/de.yml
de:
nav:
home: "Startseite"
about: "Über uns"
settings: "Einstellungen"
greeting: "Hallo, %{name}!"
cart:
item_count:
one: "%{count} Artikel"
other: "%{count} Artikel"Использовать вспомогательную функцию t()
Вспомогательная функция t() доступна во всём Rails: представлениях, контроллерах, моделях, почтовых службах и заданиях. Она принимает ключ, необязательные переменные интерполяции и такие параметры, как стандартные значения и область. В представлениях Rails поддерживает отложенные поиски, автоматически ограничивающие ключи текущими контроллером и действием.
# In views (ERB)
<h1><%= t('nav.home') %></h1>
<p><%= t('greeting', name: @user.name) %></p>
# In controllers
flash[:notice] = t('flash.product_created')
# In models
validates :name, presence: { message: I18n.t('errors.blank') }
# With HTML (safe)
<%= t('terms_html', link: link_to(t('terms_link'), '/terms')) %>Обработать формы множественного числа
Rails I18n использует категории множественного числа CLDR: zero, one, two, few, many, other. Английскому нужны только one и other, но другим языкам требуется больше форм. Определите переводы множественного числа как вложенные ключи YAML для категорий целевых языков.
# In YAML:
en:
cart:
item_count:
zero: "No items"
one: "%{count} item"
other: "%{count} items"
# Arabic (6 forms):
ar:
cart:
item_count:
zero: "لا عناصر"
one: "عنصر واحد"
two: "عنصران"
few: "%{count} عناصر"
many: "%{count} عنصرًا"
other: "%{count} عنصر"
# Usage in views:
<%= t('cart.item_count', count: @cart.items.size) %>Добавить цепочки резервных локалей
Встроенный I18n.fallbacks в Rails предоставляет только базовый переход от региональной к стандартной локали. Пользователь pt-BR при отсутствии ключа видит английский вместо pt-PT. rails-locale-chain добавляет настраиваемые цепочки глубокого объединения, чтобы региональные пользователи всегда видели ближайший доступный перевод.
# Lazy lookups use the controller/action as scope
# app/views/products/index.html.erb
# Instead of t('products.index.title'), just use:
<h1><%= t('.title') %></h1>
<p><%= t('.description') %></p>
# Rails looks up: products.index.title and products.index.description
# config/locales/en.yml
en:
products:
index:
title: "All Products"
description: "Browse our catalog"Автоматизировать перевод
После завершения настройки Rails I18n переведите файлы локалей YAML с помощью ИИ. i18n Agent изначально поддерживает YAML: укажите исходный файл локали, и он создаст все целевые языки, сохраняя вложенные ключи, переменные интерполяции и формы множественного числа.
# Gemfile
gem 'rails-locale-chain'
# config/initializers/locale_chain.rb
Rails.application.config.i18n.fallbacks = {
'pt-BR': ['pt', 'en'],
'zh-Hant-TW': ['zh-Hant', 'zh', 'en'],
'es-419': ['es', 'en'],
}
# The gem deep-merges translations across the chain
# pt-BR -> pt -> en
# Missing keys in pt-BR are filled from pt, then enРаспространённые ошибки
Ошибки InvalidPluralizationData
Отложенные поиски вне представлений
Синтаксические ошибки YAML нарушают все переводы
Попробовать i18n Agent
Перетащите сюда файл перевода
JSON, YAML, PO, XML, CSV, Markdown, Properties
или нажмите, чтобы выбрать
Целевые языки