|
文档
预约演示平台
平台MCPCLIAPI工作流
指南
更新日志

本地化

  • 概览
  • 翻译 API
  • Web 应用本地化
  • 移动应用本地化
  • iOS 与 String Catalogs
  • Android 与 strings.xml
  • 邮件本地化
  • 静态内容(如 .md、.json)
  • Next.js + Markdoc
  • Rails + i18n

工作流

  • 通过 MCP 配置引擎
  • Jira 智能分诊
  • CI/CD

使用 i18n API 实现 Ruby on Rails 本地化

Lingo.dev CLI 可通过已配置的 本地化引擎 翻译 Rails 的 config/locales YAML 文件。Rails 原生内置 i18n API——应用中所有可翻译文本都存放在按 locale 划分的 YAML 文件里。Lingo.dev 能无缝接入你现有的流程,无需额外引入运行时依赖。

本指南将带你完整走通 Rails 应用本地化流程:配置 CLI、组织按 locale 划分的 YAML 文件、在请求时切换 locale,以及用 GitHub Actions 自动化翻译。

演示仓库

克隆或 fork lingodotdev/ruby-on-rails-localization-example,即可跟着一起操作。这个仓库包含一个可运行的 Rails 应用、config/locales YAML 文件、Lingo.dev CLI 配置以及 GitHub Actions 工作流。

Rails 本地化如何运作#

Rails 会从 config/locales/ 下的 YAML 文件中读取翻译。每个文件都以 locale code 作为根键,内部则包含嵌套键,对应你在代码里通过 I18n.t 使用的查找路径。

层级存放内容示例文件
UI 文案按钮、标签、flash 消息config/locales/en.yml
邮件文案ActionMailer 的主题和正文config/locales/mailers.en.yml
模型错误校验消息和属性名config/locales/activerecord.en.yml

每个 Rails YAML 文件的第一个键都是 locale code 本身——en:、es:、fr:。CLI 的 yaml-root-key bucket 能识别这种结构:它会先去掉 locale 前缀,再把内容发送到本地化引擎;随后以目标 locale code 作为新的根键,写出对应的平行文件。嵌套键、%{name} 插值标记,以及 CLDR 复数类别(zero/one/two/few/many/other)都会被完整保留。

前提条件#

1

创建本地化引擎

每次运行 CLI,内容都会经过一个 本地化引擎——这项配置决定了要使用哪个 LLM 模型、应用哪些 术语表、品牌语气 和 指令。你可以在 Lingo.dev 控制台 中创建一个,并生成 API 密钥。

2

确认 Ruby 和 Rails 版本

本指南适用于 Rails 7.2 及以上版本,而它要求 Ruby 3.1 及以上。先检查你的版本:

bash
ruby -v
rails -v
3

确认 Node.js 版本

CLI 需要 Node.js 18 或更高版本:

bash
node -v
4

设置 Rails i18n

本指南默认你的应用已经将翻译存放在 config/locales/*.yml 中。如果你的视图或控制器里还有硬编码字符串,请先将它们提取为 t() 调用。比如,把下面这段替换成:

erb
<h1>Welcome</h1>

替换为:

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

然后把对应的键添加到 config/locales/en.yml 中。完整迁移步骤可参考 Rails 的 internationalization guide。

组织翻译文件#

Rails 会自动加载 config/locales/ 下所有匹配的 *.yml 文件。建议将源 locale 和各个目标语言文件放在同一目录中,让这个目录成为唯一可信来源:

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#

在项目根目录创建一个 i18n.json 文件,并声明一个指向 locale 文件的 yaml-root-key bucket:

json
{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de"]
  },
  "buckets": {
    "yaml-root-key": {
      "include": ["config/locales/[locale].yml"]
    }
  }
}

[locale] 占位符会解析为每个已配置的 locale code。使用 source: "en" 时,CLI 会读取 config/locales/en.yml,并把翻译后的文件写入 config/locales/es.yml、config/locales/fr.yml 和 config/locales/de.yml。

Rails 可以与 en.yml 一起正常加载 mailers.en.yml、pages.en.yml 等文件。只需把更多模式添加到 yaml-root-key bucket 的 include 数组中:

json
{
  "buckets": {
    "yaml-root-key": {
      "include": [
        "config/locales/[locale].yml",
        "config/locales/mailers.[locale].yml",
        "config/locales/pages.[locale].yml"
      ]
    }
  }
}

为多个 locale 配置 Rails#

告诉 Rails 哪些 locale 可用,以及默认使用哪个。在 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 请求头选择当前请求的 locale:

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

在视图中渲染翻译#

在 ERB 模板中使用 t 和 l 辅助方法。键名前面的点会相对于当前视图路径解析,让翻译键与使用它们的模板就近放置:

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" %>

在布局中添加一个语言切换器:

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

在本地执行翻译#

设置好 API 密钥后,运行 CLI:

bash
export LINGO_API_KEY="your-api-key"
npx lingo.dev@latest run

CLI 会读取所有匹配 bucket 模式的文件,借助 lockfile 识别尚未翻译的条目,通过本地化引擎翻译增量内容,并将结果写入各个目标 locale 文件。locale 根键、嵌套命名空间、%{name} 风格的插值标记以及复数类别都会被保留——变化的只有可翻译文本。

开发过程中,如果只想处理某个特定 locale:

bash
npx lingo.dev@latest run --target-locale es

首次运行翻译后,请重启 Rails 服务器,以便加载新的 YAML 文件:

bash
bin/rails server

访问 /es 查看西班牙语效果。

复数形式#

Rails 使用 CLDR 复数类别——zero、one、two、few、many、other。给 I18n.t 传入 count: 参数后,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 会在原位翻译每一种复数变体。如果目标 locale 需要比英语的 one/other 更多的类别,请在源 en.yml 中先定义好。

用 GitHub Actions 实现自动化#

在 .github/workflows/translate.yml 添加工作流文件,让每次 push 都自动触发翻译:

翻译直接提交到 main——零阻力,非常适合小团队:

yaml
name: Translate
on:
  push:
    branches: [main]
permissions:
  contents: write
jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Lingo.dev
        uses: lingodotdev/lingo.dev@main
        with:
          api-key: ${{ secrets.LINGODOTDEV_API_KEY }}

在 GitHub 仓库的 Settings > Secrets and variables > Actions 中,将你的 API 密钥保存为 LINGODOTDEV_API_KEY。

部署前验证#

使用 --frozen 标志作为部署门禁,确保不会把未翻译内容发布到生产环境。如果仍有条目待翻译,CLI 会以非零状态码退出:

bash
npx lingo.dev@latest run --frozen

将它作为独立的 CI 步骤,放在资源预编译或容器构建之前:

yaml
- name: Verify translations
  run: npx lingo.dev@latest run --frozen
- name: Precompile assets
  run: bundle exec rails assets:precompile

下一步#

静态内容本地化
支持 Markdown、MDX、JSON、YAML 等更多 bucket 类型
Web 应用本地化
覆盖常见 Web 框架的 UI 文案模式
CI/CD 工作流
GitHub Actions、GitLab CI、Bitbucket Pipelines 等模式
术语表
锁定品牌名和技术术语,避免被误译

这个页面对你有帮助吗?

Max PrilutskiyMax Prilutskiy·已更新 2 个月前·3 分钟阅读