PTC

Internazionalizzazione (i18n) di Rails: guida completa

Configura I18n di Rails, organizza config/locales/*.yml, automatizza le traduzioni YAML con l'IA e lascia che PTC (Private Translation Cloud) esegua la revisione della tua app Rails in esecuzione a ogni release. Alla fine avrai un'app Rails che risponde agli URL /es/..., fornisce viste tradotte in oltre 40 lingue ed è verificata tramite revisione visiva.

Questa guida presuppone che tu abbia un'app Rails 7+ esistente. I concetti si applicano alle versioni precedenti di Rails con differenze minori nelle API. La gem I18n stessa è stabile da anni. Per un quadro più ampio sulla localizzazione CI/CD in vari stack, vedi Localizzazione software con IA creata per le pipeline CI/CD.

Configura Rails per caricare i locale, riconoscere gli URL e cambiare per ogni richiesta

L'internazionalizzazione di Rails richiede tre passaggi di configurazione. Imposta i locale disponibili, aggiungi il locale ai tuoi URL e fai in modo che Rails carichi il locale corretto per ogni richiesta. Installa anche la gem rails-i18n per i dati dei locale.

Dichiara i locale disponibili in config/application.rb

In config/application.rb, indica a Rails quali lingue supporta l'app e impostane una predefinita:

module MyApp
  class Application < Rails::Application
    config.i18n.available_locales = [:en, :es, :fr, :de, :ja]
    config.i18n.default_locale = :en
    config.i18n.fallbacks = true
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
  end
end

La riga load_path += Dir[...] è quella fondamentale. Per impostazione predefinita, Rails carica solo config/locales/*.yml (un livello di profondità). Aggiungere il glob ricorsivo ti consente di organizzare le traduzioni per namespace, modello o funzionalità in sottocartelle.

Aggiungi :locale all'ambito del tuo URL

Aggiungi un ambito :locale in modo che ogni lingua abbia il proprio percorso, come /en/time o /es/time:

# config/routes.rb
scope "/:locale" do
  get '/time', to: 'home#index', as: :time_display
end

Cambia locale per richiesta con I18n.with_locale

In ApplicationController, carica il locale corretto dall'URL e includilo in tutti i link generati:

class ApplicationController < ActionController::Base
  around_action :switch_locale

  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

I18n.with_locale è il modo idiomatico per limitare un locale a una richiesta. Imposta il locale, esegue il blocco, ripristina il locale precedente ed è thread-safe. default_url_options assicura che ogni URL generato da Rails contenga il locale corrente, in modo che gli utenti mantengano la lingua selezionata durante la navigazione.

Installa rails-i18n per i nomi dei mesi tradotti e le regole di pluralizzazione

La gem rails-i18n fornisce i dati dei locale per decine di lingue. Questa gem include i nomi dei mesi tradotti, le regole di pluralizzazione e i messaggi di errore predefiniti di Rails. Così non dovrai tradurre tu stesso questo testo standard.

# Gemfile
gem 'rails-i18n'
bundle install

La tua app Rails è ora completamente configurata per l'internazionalizzazione.

Aggiungi un selettore di lingua con url_for(locale: :code)

Poiché default_url_options include automaticamente il locale in ogni URL generato, il tuo selettore deve solo aggiornare il parametro :locale mantenendo l'utente sulla stessa pagina.

<%# app/views/layouts/application.html.erb %>
<nav class="language-switcher">
  <%= link_to "English", url_for(locale: :en) %> |
  <%= link_to "Español", url_for(locale: :es) %> |
  <%= link_to "Deutsch", url_for(locale: :de) %>
</nav>

Ogni link usa url_for(locale: :code) per generare un URL con il locale specificato. Quando gli utenti cliccano, switch_locale in ApplicationController rileva la modifica e Rails visualizza la pagina nella nuova lingua.

Sostituisci il testo hardcoded nelle viste con t(:key)

Il testo hardcoded non apparirà nei tuoi file YAML, il che significa che non può essere tradotto. Usa sempre le chiavi di traduzione per qualsiasi testo rivolto all'utente.

<%# Correct - uses translation keys %>
<h1><%= t(:hello) %></h1>
<p><%= t(:current_time, time: @time) %></p>
<button id="click-me"><%= t(:refresh) %></button>

<%# Incorrect - hardcoded text %>
<h1>Hello</h1>
<p>Current time: <%= @time %></p>
<button>Refresh</button>

Nei controller (per i flash messages):

def create
  if @post.save
    redirect_to @post, notice: t('flash.post.created')
  else
    flash.now[:alert] = t('flash.post.error')
    render :new, status: :unprocessable_entity
  end
end

Nei modelli (per i messaggi di convalida, usa le convenzioni di Active Model):

# config/locales/en.yml
en:
  activerecord:
    attributes:
      post:
        title: "Title"
    errors:
      models:
        post:
          attributes:
            title:
              blank: "is required"

Interpola le variabili con %{name}

%{name} nello YAML viene sostituito dal valore che passi a t():

current_time: "Current time: %{time}"
<%= t(:current_time, time: @time) %>

Usa il lazy lookup (.key) per le traduzioni con ambito a livello di vista

Quando le tue chiavi di traduzione sono organizzate in modo da corrispondere alla struttura delle cartelle delle tue viste, usa un punto iniziale. Rails inserisce il prefisso dalla vista corrente:

<%# Instead of this: %>
<%= t('home.index.hello') %>

<%# Use this: %>
<%= t('.hello') %>

Rails vede che ti trovi in home/index.html.erb e antepone home.index.. Se ridenomini o sposti una vista, i percorsi del lazy lookup si aggiornano automaticamente.

Organizza config/locales/ per funzionalità invece di un enorme en.yml

Per un'app reale, un enorme en.yml diventa impossibile da gestire. Organizza per funzionalità:

config/locales/
  en.yml                       # global / shared keys
  models/
    post.en.yml
  views/
    posts.en.yml
    home.en.yml
  flash.en.yml

Un esempio di config/locales/views/posts.en.yml:

en:
  posts:
    index:
      title: "All Posts"
      empty: "No posts yet"
    new:
      title: "Create a New Post"
    show:
      published_at: "Published %{date}"
      comments_count:
        zero: "No comments yet"
        one: "1 comment"
        other: "%{count} comments"

Convenzioni:

  • Chiavi nidificate raggruppano stringhe correlate e abilitano il lazy lookup.
  • Interpolazione %{name} per le variabili inline.
  • Chiavi di pluralizzazione zero / one / other per i nomi numerabili. Rails indirizza alla chiave corretta in base a count:: t('posts.show.comments_count', count: 5).

Aggiungi anche le stringhe JavaScript allo YAML

Rails non estrae automaticamente il testo dai file JavaScript. Qualsiasi testo lato client (avvisi, tooltip, messaggi di conferma) deve risiedere nel tuo YAML in modo da essere tradotto insieme a tutto il resto:

en:
  confirm: "Are you sure?"

Quando traduci con PTC nella sezione successiva, queste stringhe viaggiano insieme al resto.

Traduci config/locales/*.en.yml con PTC in 4 passaggi

Una volta che i tuoi file di traduzione sono al loro posto, hai bisogno di versioni per ogni lingua di destinazione. PTC si occupa di questo:

  1. Avvia un progetto PTC e scegli l'inglese come origine. La prova copre 20.000 parole in 2 lingue, nessuna carta di credito.
  2. Carica i tuoi file config/locales/*.en.yml. PTC analizza lo YAML, riconosce le chiavi di pluralizzazione di Rails (zero, one, other, few, many) e preserva le interpolazioni %{name}.
  3. Aggiungi una breve descrizione della tua app Rails e del pubblico. PTC usa questo contesto per tradurre con il tono e la terminologia corretti.
  4. Scegli le lingue di destinazione e conferma. PTC produce posts.es.yml, posts.fr.yml, posts.de.yml, strutturalmente identici all'origine ma con i valori tradotti. Le forme plurali vengono generate per ciascuna lingua. Il polacco ottiene one / few / many / other. Il giapponese ottiene solo other.

Inserisci nuovamente i file in config/locales/views/, riavvia il tuo server Rails e l'app fornirà le nuove lingue.

Per i progetti basati su Git, collega PTC al tuo repository. Le nuove stringhe in qualsiasi *.en.yml attivano la traduzione automatica. PTC apre un merge request con i file aggiornati nella lingua di destinazione. Consulta il riferimento API di PTC per gli endpoint sottostanti.

Usa I18n.with_locale in job in background, mailer e task cron

Il pattern I18n.with_locale(locale, &block) è fondamentale per qualsiasi codice eseguito al di fuori di una normale richiesta. Ciò include job in background, task cron e mailer.

# Background job: send an email in the user's preferred locale
class WelcomeEmailJob < ApplicationJob
  def perform(user_id)
    user = User.find(user_id)
    I18n.with_locale(user.preferred_locale) do
      UserMailer.welcome(user).deliver_now
    end
  end
end

Senza with_locale, il job viene eseguito nel locale che era attivo all'avvio del worker. Di solito :en, indipendentemente dalla preferenza dell'utente. Con esso, l'email viene visualizzata nella lingua dell'utente e il locale viene ripristinato al termine del blocco.

Esporta le traduzioni Rails in JSON con i18n-js per l'uso lato client

Le pagine visualizzate da Rails ottengono le traduzioni tramite t() in ERB. Il codice JavaScript eseguito nel browser non vede direttamente I18n di Rails. Il pattern più pulito usa la gem i18n-js per esportare le traduzioni in formato JSON e caricarle lato client.

# Gemfile
gem 'i18n-js'
bundle install
i18n init

Aggiorna la configurazione generata per esportare le traduzioni in public/locales.json:

# config/i18n.rb
require "i18n-js"

I18n::JS.config do |config|
  config.export_i18n_js = false
  config.translations_path = "public/locales.json"
end

Genera il file JSON:

i18n export

Questo legge tutti i tuoi file YAML (en.yml, es.yml, de.yml) e scrive public/locales.json con ogni traduzione in un formato leggibile da JS.

Blocca la versione di i18n-js con Importmap di Rails 7+:

# config/importmap.rb
pin "i18n-js", to: "https://esm.sh/i18n-js@latest/dist/import/index.js"
pin "load_locale", to: "load_locale.js"

Crea un loader:

// app/javascript/load_locale.js
export async function loadLocale() {
  const response = await fetch('/locales.json');
  return await response.json();
}

Passa il locale corrente a JavaScript tramite il tag <body>:

<%# app/views/layouts/application.html.erb %>
<body data-locale="<%= I18n.locale %>">

Quindi usa le traduzioni nel tuo JavaScript:

// app/javascript/application.js
import { I18n } from "i18n-js";
import { loadLocale } from "./load_locale";

document.addEventListener('turbo:load', async () => {
  const translations = await loadLocale();
  const i18n = new I18n(translations);
  i18n.locale = document.body.dataset['locale'];

  if (confirm(i18n.t('confirm'))) {
    // User clicked OK
  }
});

i18n.t() funziona come l'helper t di Rails. Quando gli utenti cambiano lingua, JavaScript usa le traduzioni corrette dall'attributo data-locale.

Traduci i contenuti ActiveRecord con l'API di PTC

Il pattern precedente traduce le stringhe statiche nei tuoi file YAML. I contenuti ActiveRecord (post degli utenti, commenti, descrizioni dei prodotti memorizzate come input dell'utente) non compaiono nello YAML e richiedono un approccio diverso. L'API REST di PTC traduce questi contenuti su richiesta con autenticazione con token Bearer, usando lo stesso glossario e la stessa voce del brand dei tuoi file config/locales/*.yml. Invia i tuoi contenuti a PTC tramite POST, quindi ricevi un callback quando le traduzioni sono pronte o esegui il polling dello stato da un job in background.

Localizza date, numeri e valute con gli helper di Rails

Date e orari. Usa l'helper l (abbreviazione di localize):

<%= l Time.now, format: :long %>

La gem rails-i18n fornisce i formati di data/ora predefiniti per molte lingue, inclusi i nomi dei mesi tradotti e la formattazione specifica del locale. Puoi definire formati personalizzati nei tuoi file YAML.

Numeri e valute. Rails include helper sensibili al locale:

<%= number_to_currency(100, locale: :es) %>   <!-- 100,00 € -->
<%= number_with_delimiter(1000000) %>          <!-- 1,000,000 -->

Questi rispettano le convenzioni del locale per i separatori decimali, i delimitatori delle migliaia e i simboli delle valute.

Viste localizzate per lingua. Per le pagine con contenuti significativamente diversi a seconda del locale, crea file di vista separati. Rails visualizza la vista appropriata in base al locale corrente:

app/views/pages/
  about.html.erb       <!-- Default -->
  about.es.html.erb    <!-- Spanish version -->
  about.de.html.erb    <!-- German version -->

Revisione visiva della traduzione della tua app Rails in esecuzione: rilascia senza QA manuale a ogni release

Dopo che PTC ha tradotto i tuoi config/locales/*.yml, l'app Rails visualizzata necessita ancora di verifica. Un'etichetta tradotta potrebbe andare in overflow rispetto a un pulsante in tedesco. Un messaggio di convalida in francese potrebbe usare la forma grammaticale errata. Una stringa hardcoded in inglese in un template ERB (nessuna chiamata t()) verrà visualizzata non tradotta, indipendentemente dal numero di lingue che rilasci.

AI Visual QA di PTC sostituisce il ciclo di QA manuale. Per le app Rails (basate su browser), installa l'estensione del browser di PTC e registra un percorso guidato delle schermate critiche della tua app (accesso, flussi principali, pagine di amministrazione). Da quel momento in poi, PTC riproduce la registrazione in ogni lingua di destinazione dopo ogni aggiornamento della traduzione, acquisisce ogni schermata e segnala:

  • Correzioni nei file YAML quando PTC li gestisce. PTC ritraduce un'accezione errata, sceglie un sinonimo più corto o rigenera una forma plurale.
  • Prompt di Cursor / Claude Code quando il problema risiede nel tuo codice Ruby o ERB. Una stringa hardcoded in inglese al di fuori di t(), un flash message costruito tramite concatenazione invece di interpolazione o un helper che dovrebbe usare I18n.l per la formattazione della data.

Il risultato: un'app Rails multilingue verificata a ogni release. Non solo YAML tradotto.

Traduci note di rilascio, mailer di Devise e pagine di marketing

Le tue note di rilascio, le email rivolte ai clienti inviate tramite Devise o Action Mailer e le pagine di marketing risiedono al di fuori di config/locales. Paste to Translate di PTC gestisce questi testi nello stesso progetto. Incolla il testo di origine nel pannello di controllo di PTC, scegli le lingue di destinazione e ottieni traduzioni che usano lo stesso glossario e la stessa voce del brand delle tue traduzioni YAML.

Traduci i tuoi file config/locales/*.yml con PTC

Inizia la tua prova di 30 giorni: 20.000 parole in 2 lingue, nessuna carta di credito. Carica i tuoi file YAML, ottieni le versioni tradotte in pochi minuti, quindi installa l'estensione del browser per verificare la tua app Rails in esecuzione.

Correlati: