|
Документация
Заказать демоПлатформа
ПлатформаMCPCLIAPIРабочие процессы
Руководства
Журнал изменений

Локализация

  • Обзор
  • API локализации
  • Локализация веб-приложений
  • Локализация мобильных приложений
  • iOS и String Catalogs
  • Android и strings.xml
  • Локализация email-писем
  • Статический контент, например .md и .json
  • Next.js с Markdoc
  • Rails с i18n

Рабочие процессы

  • Настройка движка с MCP
  • Jira Triage
  • CI/CD

Локализация Ruby on Rails через API i18n

CLI Lingo.dev переводит Rails YAML-файлы config/locales через настроенный движок локализации. В Rails i18n API встроен из коробки, поэтому весь переводимый текст приложения хранится в отдельных YAML-файлах для каждой локали. Lingo.dev легко встраивается в существующий пайплайн и не добавляет зависимостей во время выполнения.

В этом руководстве — полная локализация Rails-приложения: настройка CLI, организация YAML-файлов по локалям, переключение локалей при запросе и автоматизация переводов в CI.

Демо-репозиторий

Клонируйте или сделайте форк lingodotdev/ruby-on-rails-localization-example, чтобы следовать примерам. Это рабочее Rails-приложение с YAML-файлами config/locales, готовым .lingo/config.json и уже добавленными переводами — конфигурацию можно сразу читать рядом с результатом, который она даёт.

Как устроена локализация в Rails#

Rails читает переводы из YAML-файлов в каталоге config/locales/. В корне каждого файла находится ключ с кодом локали, а внутри — вложенные ключи, повторяющие пути поиска, которые ваш код использует через I18n.t.

СлойЧто здесь хранитсяПример файла
Строки интерфейсаКнопки, метки, flash-сообщенияconfig/locales/en.yml
Тексты писемТемы и содержимое для ActionMailerconfig/locales/mailers.en.yml
Ошибки моделейСообщения валидации и названия атрибутовconfig/locales/activerecord.en.yml

Первый ключ каждого YAML-файла Rails — это код локали: en:, es:, fr:. Rails индексирует переводы по этому корневому ключу, а не по имени файла: загружает все файлы из config/locales/ и сохраняет содержимое каждого под тем корнем, который в нём объявлен. Поэтому файл es.yml с корнем en: не игнорируется — он вливается в пространство имён en. В итоге у испанского не остаётся переводов, а английские тихо перезаписываются.

Перевести этот формат — значит переписать сам ключ, а не только значения. Формат yaml-root-key делает именно это: обходит дерево под корневым ключом, переводит только строковые значения и записывает целевой файл с корнем целевой локали. Вложенные ключи, токены интерполяции %{name} и категории множественного числа CLDR (zero/one/two/few/many/other) — структурные элементы, они переносятся без изменений, как и комментарии с якорями YAML.

Что понадобится#

1

Создайте движок локализации

Каждый запуск CLI обрабатывает контент через движок локализации — это конфигурация, которая задаёт LLM-модель, глоссарий, тональность бренда и правила. Создайте движок в Lingo.dev dashboard и получите API-ключ.

2

Проверьте Ruby и Rails

Это руководство рассчитано на Rails 7.2 и выше, а для него нужен Ruby 3.1 или новее. Проверьте свои версии:

bash
ruby -v
rails -v
3

Проверьте Node.js

CLI требует Node.js версии 22 или выше:

bash
node -v
4

Настройте i18n в Rails

Предполагается, что ваше приложение уже хранит переводы в config/locales/*.yml. Если в представлениях или контроллерах ещё остались захардкоженные строки, сначала вынесите их в вызовы t(). Например, замените:

erb
<h1>Welcome</h1>

на:

erb
<h1><%= t(".welcome") %></h1>

затем добавьте соответствующий ключ в config/locales/en.yml. Полный процесс миграции описан в руководстве Rails по интернационализации.

Организуйте файлы переводов#

Rails автоматически загружает каждый файл *.yml из каталога config/locales/. Храните исходную локаль рядом с переведёнными версиями, чтобы каталог оставался единым источником истины:

text
config/locales/
  en.yml          # Source locale
  es.yml          # Generated by Lingo.dev
  fr.yml
  de.yml

Типичный файл en.yml сочетает обычные строки, вложенные пространства имён, интерполяцию %{name} и формы множественного числа:

yaml
en:
  hello: "Hello"
  home:
    welcome: "Welcome, %{name}!"
    cta: "Get started"
  notifications:
    unread:
      zero: "No unread notifications"
      one: "1 unread notification"
      other: "%{count} unread notifications"
  errors:
    messages:
      blank: "can't be blank"

Настройте CLI#

Установите CLI, авторизуйтесь и привяжите проект к движку:

bash
npm install -g @lingo.dev/cli
lingo login
lingo init
lingo link

lingo init и lingo link создают .lingo/config.json с вашими локалями, а также orgId и engineId движка. Зафиксируйте файл в репозитории вместе с .lingo/lock.json — так каждая машина и каждый запуск CI будут работать с одним состоянием.

Добавьте запись files[], указывающую на файл исходной локали, и явно задайте формат:

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de"],
  "files": [{ "pattern": "config/locales/en.yml", "format": "yaml-root-key" }]
}

"format": "yaml-root-key" здесь обязателен — не опционален. По пути .yml невозможно понять, является ли корневой ключ локалью или обычной конфигурацией, поэтому CLI не угадывает: без format файл обрабатывается как обычный yaml — значения переводятся, а корень остаётся en:. Это и есть та тихая ошибка, о которой говорилось выше.

Целевые файлы формируются из пути к исходному, поэтому config/locales/en.yml даёт config/locales/es.yml, config/locales/fr.yml и config/locales/de.yml.

Rails также загружает файлы по модулям рядом с en.yml — devise.en.yml, mailers.en.yml, activerecord.en.yml. Добавьте вторую запись с glob, чтобы охватить их:

json
{
  "files": [
    { "pattern": "config/locales/en.yml", "format": "yaml-root-key" },
    { "pattern": "config/locales/*.en.yml", "format": "yaml-root-key" }
  ]
}

Два паттерна не пересекаются: первый совпадает только с en.yml, второй — только с файлами, оканчивающимися на .en.yml, поэтому уже переведённые файлы вроде es.yml и devise.es.yml никогда не попадут в источники. devise.en.yml даёт devise.es.yml.

Настройте Rails для нескольких локалей#

Укажите Rails, какие локали доступны и какая должна использоваться по умолчанию. В config/application.rb:

ruby
module YourApp
  class Application < Rails::Application
    config.i18n.available_locales = [:en, :es, :fr, :de]
    config.i18n.default_locale = :en
    config.i18n.fallbacks = [:en]
  end
end

Выбирайте локаль запроса в ApplicationController по параметру URL или заголовку Accept-Language:

ruby
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    locale = params[:locale] || http_accept_locale || I18n.default_locale
    I18n.with_locale(locale, &action)
  end

  def http_accept_locale
    header = request.headers["Accept-Language"].to_s
    header.scan(/[a-z]{2}/).find { |l| I18n.available_locales.map(&:to_s).include?(l) }
  end

  def default_url_options
    { locale: I18n.locale }
  end
end

Выводите переводы в представлениях#

Используйте хелперы t и l в ERB-шаблонах. Точка в начале ключа вычисляется относительно текущего пути представления, поэтому ключи переводов остаются рядом с шаблонами, где они используются:

erb
<h1><%= t(".welcome", name: @user_name) %></h1>
<p><%= t("notifications.unread", count: @unread_count) %></p>
<%= link_to t(".cta"), signup_path, class: "btn-primary" %>

Добавьте в layout переключатель локали:

erb
<nav>
  <% I18n.available_locales.each do |locale| %>
    <%= link_to locale.upcase, url_for(locale: locale) %>
  <% end %>
</nav>

Переводите локально#

bash
lingo push --wait

push загружает исходные файлы, прогоняет их через движок локализации и записывает переведённые файлы обратно. --wait блокирует команду до получения результатов — стоит передавать явно, потому что в ожидающем релизе поведение по умолчанию меняется: push отправляет задачу и сразу возвращает управление, а результаты придётся собирать через lingo pull.

Последующие запуски переводят только изменения: push хэширует источник и сравнивает с .lingo/lock.json, так что неизменённые записи ресурсов не расходуют. Первый запуск на проекте — или после добавления локали — требует обработки всего корпуса:

bash
lingo push --backfill-missing

Чтобы ограничить запуск частью файлов, передайте glob:

bash
lingo push "config/locales/**"

Чтобы забрать результаты, созданные в другом месте — на другой машине или в CI, — выполните lingo pull.

После первого запуска перевода перезапустите сервер Rails, чтобы он подхватил новые YAML-файлы:

bash
bin/rails server

Откройте /es, чтобы посмотреть испанский вариант.

Множественное число#

Rails использует категории множественного числа CLDR — zero, one, two, few, many, other. Передайте аргумент count: в I18n.t, и Rails сам выберет подходящий ключ:

ruby
t("notifications.unread", count: 0)   # => "No unread notifications"
t("notifications.unread", count: 1)   # => "1 unread notification"
t("notifications.unread", count: 12)  # => "12 unread notifications"

CLI переводит каждый вариант множественного числа прямо на месте. Если целевой локали нужно больше категорий, чем английские one/other, добавьте их в исходный en.yml.

Автоматизация в CI#

Lingo.dev GitHub App переводит при каждом пуше и пул-реквесте на стороне сервера — без раннера и без API-ключа в репозитории. Движок определяется из зафиксированного .lingo/config.json, поэтому orgId и engineId должны быть в файле, который вы коммитите.

Если вы предпочитаете запускать CLI в собственном пайплайне — GitHub Actions, GitLab CI, Bitbucket Pipelines — см. CI/CD Рабочие процессы. Передайте LINGO_API_KEY как секрет и вызовите lingo push --wait как обычный шаг сборки.

Проверяйте перед деплоем#

Используйте lingo check как шлюз деплоя, чтобы непереведённый контент не попал в продакшен. Команда завершается с ненулевым статусом, если остались записи без перевода, и ничего не записывает:

bash
lingo check

Добавьте это как отдельный шаг CI перед компиляцией ассетов или сборкой контейнера:

yaml
- name: Verify translations
  run: lingo check
- name: Precompile assets
  run: bundle exec rails assets:precompile

Что дальше#

Локализация статического контента
Markdown, MDX, JSON, YAML и другие форматы статических файлов
Локализация веб-приложений
Паттерны строк интерфейса для популярных веб-фреймворков
Рабочие процессы CI/CD
Паттерны для GitHub Actions, GitLab CI и Bitbucket Pipelines
Глоссарии
Зафиксируйте названия брендов и технические термины, чтобы они не переводились

Эта страница была полезной?

Max PrilutskiyMax Prilutskiy·Обновлено 8 дней назад·6 минут чтения