|
Documentación
Agenda una demoPlataforma
PlataformaMCPCLIAPIFlujos de trabajo
Guías
Registro de cambios

Localización

  • Resumen
  • API de traducción
  • Localización de apps web
  • Localización de apps móviles
  • iOS con String Catalogs
  • Android con strings.xml
  • Localización de emails
  • Contenido estático (p. ej., .md, .json)
  • Next.js con Markdoc
  • Rails con i18n

Flujos de trabajo

  • Configuración del motor con MCP
  • Triaje de Jira
  • CI/CD

Localización de Ruby on Rails con la API de i18n

La CLI de Lingo.dev traduce archivos YAML de Rails config/locales mediante un motor de localización configurado. Rails trae la API de i18n integrada de forma nativa: el texto traducible de tu app vive en archivos YAML por idioma. Lingo.dev encaja en tu pipeline actual sin añadir dependencias en tiempo de ejecución.

Esta guía te acompaña paso a paso para localizar una app de Rails de punta a punta: configurar la CLI, organizar archivos YAML por idioma, cambiar el idioma en tiempo de solicitud y automatizar traducciones con GitHub Actions.

Repositorio de demo

Clona o haz fork de lingodotdev/ruby-on-rails-localization-example para seguir el recorrido. El repositorio incluye una app de Rails funcional con archivos YAML config/locales, una configuración de la CLI de Lingo.dev y un flujo de trabajo de GitHub Actions.

Cómo funciona la localización en Rails#

Rails lee las traducciones desde los archivos YAML en config/locales/. Cada archivo usa un código de idioma como clave raíz y contiene claves anidadas que reflejan las rutas de búsqueda que tu código usa con I18n.t.

CapaQué contieneArchivo de ejemplo
Textos de UIBotones, etiquetas, mensajes flashconfig/locales/en.yml
Copys de correoAsuntos y cuerpos para ActionMailerconfig/locales/mailers.en.yml
Errores del modeloMensajes de validación y nombres de atributosconfig/locales/activerecord.en.yml

La primera clave de cada archivo YAML de Rails es el propio código de idioma: en:, es:, fr:. El bucket yaml-root-key de la CLI entiende esta estructura: elimina el prefijo del idioma antes de enviar el contenido a tu motor de localización y luego escribe un archivo paralelo con el código del idioma de destino como nueva clave raíz. Se conservan las claves anidadas, los tokens de interpolación %{name} y las categorías de plural de CLDR (zero/one/two/few/many/other).

Requisitos previos#

1

Crea un motor de localización

Cada ejecución de la CLI envía el contenido a través de un motor de localización: la configuración que define qué modelo LLM, glosario, voz de marca e instrucciones se aplican. Crea uno en el dashboard de Lingo.dev y genera una API key.

2

Verifica Ruby y Rails

Esta guía está pensada para Rails 7.2 o superior, que requiere Ruby 3.1 o superior. Revisa tus versiones:

bash
ruby -v
rails -v
3

Verifica Node.js

La CLI requiere Node.js 18 o superior:

bash
node -v
4

Configura i18n en Rails

Esta guía asume que tu app ya guarda las traducciones en config/locales/*.yml. Si tienes cadenas hardcodeadas en vistas o controladores, primero extráelas a llamadas de t(). Por ejemplo, reemplaza:

erb
<h1>Welcome</h1>

por:

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

y luego agrega la clave correspondiente en config/locales/en.yml. Consulta la guía de internacionalización de Rails para ver todos los pasos de migración.

Organiza los archivos de traducción#

Rails carga automáticamente cada archivo *.yml dentro de config/locales/. Mantén el idioma de origen junto a sus versiones traducidas para que el directorio funcione como fuente única de verdad:

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

Un archivo en.yml típico combina cadenas simples, espacios de nombres anidados, interpolación %{name} y pluralización:

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"

Configura la CLI#

Crea un archivo i18n.json en la raíz de tu proyecto. Declara un bucket yaml-root-key que apunte a los archivos de idioma:

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"]
    }
  }
}

El placeholder [locale] se resuelve en cada código de idioma configurado. Con source: "en", la CLI lee config/locales/en.yml y escribe los archivos traducidos en config/locales/es.yml, config/locales/fr.yml y config/locales/de.yml.

Rails carga sin problema mailers.en.yml, pages.en.yml y así sucesivamente junto con en.yml. Agrega patrones adicionales al arreglo include de tu bucket yaml-root-key:

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

Configura Rails para varios idiomas#

Indícale a Rails qué idiomas están disponibles y cuál debe usar por defecto. En 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

Selecciona el idioma de la solicitud en ApplicationController a partir de un parámetro en la URL o del encabezado 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

Renderiza traducciones en las vistas#

Usa los helpers t y l en las plantillas ERB. Un punto al inicio de la clave se resuelve en función de la ruta de la vista actual, lo que mantiene las claves de traducción junto a las plantillas que las usan:

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

Agrega un selector de idioma a tu layout:

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

Traduce localmente#

Configura tu API key y ejecuta la CLI:

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

La CLI lee cada archivo que coincide con los patrones de tu bucket, identifica las entradas sin traducir con el lockfile, traduce el delta a través de tu motor de localización y escribe los resultados en cada archivo del idioma de destino. Se conservan la clave raíz del idioma, los espacios de nombres anidados, los tokens de interpolación estilo %{name} y las categorías de plural: solo cambia el texto traducible.

Para apuntar a un idioma específico durante el desarrollo:

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

Reinicia el servidor de Rails después de la primera ejecución de traducción para que se carguen los nuevos archivos YAML:

bash
bin/rails server

Visita /es para ver la versión en español.

Plurales#

Rails usa categorías de plural de CLDR: zero, one, two, few, many, other. Pasa un argumento count: a I18n.t y Rails elegirá la clave correspondiente:

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"

La CLI traduce cada variante plural en su lugar. Si tu idioma de destino necesita más categorías que one/other en inglés, defínelas en tu archivo fuente en.yml.

Automatiza con GitHub Actions#

Agrega un archivo de flujo de trabajo en .github/workflows/translate.yml para traducir en cada push:

Las traducciones se confirman directamente en main: cero fricción, ideal para equipos pequeños:

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 }}

Guarda tu API key como LINGODOTDEV_API_KEY en Settings > Secrets and variables > Actions de tu repositorio de GitHub.

Verifica antes de desplegar#

Usa la bandera --frozen como gate de despliegue para asegurarte de que no llegue contenido sin traducir a producción. La CLI termina con un estado distinto de cero si alguna entrada necesita traducción:

bash
npx lingo.dev@latest run --frozen

Agrega esto como un paso de CI independiente antes de la precompilación de assets o de la construcción del contenedor:

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

Próximos pasos#

Localización de contenido estático
Buckets para Markdown, MDX, JSON, YAML y más
Localización de apps web
Patrones de textos de UI en frameworks web comunes
Flujos de trabajo de CI/CD
Patrones para GitHub Actions, GitLab CI y Bitbucket Pipelines
Glosarios
Protege los nombres de marca y los términos técnicos para que no se traduzcan

¿Te resultó útil esta página?

Max PrilutskiyMax Prilutskiy·Actualizado hace 2 meses·6 min de lectura