PTC

Internazionalizzazione di Rails (i18n): Guida completa

Configura Rails I18n, organizza config/locales/*.yml, automatizza le traduzioni YAML con l'IA e lascia che PTC (Private Translation Cloud) revisioni la tua app Rails in esecuzione a ogni rilascio. Alla fine avrai un'app Rails che risponde agli URL /es/..., serve 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 piccole differenze nelle API. La gemma I18n stessa è stabile da anni. Per la gestione più ampia della localizzazione in ambito CI/CD su diversi stack, vedi Localizzazione software con IA integrata nelle pipeline CI/CD.

Configura Rails per caricare le lingue, riconoscere gli URL e cambiare lingua a ogni richiesta

L'internazionalizzazione di Rails richiede tre passaggi di configurazione. Imposta le lingue disponibili, aggiungi la lingua ai tuoi URL e fai in modo che Rails carichi la lingua corretta per ogni richiesta. Installa anche la gemma rails-i18n per i dati sulle lingue.

Dichiara le lingue disponibili in config/application.rb

In config/application.rb, comunica a Rails quali lingue supporta l'app e imposta quella 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à). L'aggiunta del glob ricorsivo ti permette di organizzare le traduzioni per namespace, modello o funzionalità in sottodirectory.

Aggiungi :locale allo scope del tuo URL

Aggiungi uno scope :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 lingua a ogni richiesta con I18n.with_locale

In ApplicationController, carica la lingua corretta dall'URL e includila 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 isolare la lingua per una singola richiesta. Imposta la lingua, esegue il blocco, ripristina la lingua precedente ed è thread-safe. default_url_options assicura che ogni URL generato da Rails porti con sé la lingua corrente, così gli utenti rimangono nella lingua selezionata durante la navigazione.

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

La gemma rails-i18n fornisce dati linguistici per decine di lingue. Questa gemma include i nomi dei mesi tradotti, le regole di pluralizzazione e i messaggi di errore predefiniti di Rails. In questo modo 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 la lingua 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 utilizza url_for(locale: :code) per generare un URL con la lingua specificata. Quando gli utenti cliccano, switch_locale in ApplicationController rileva la modifica e Rails renderizza 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 messaggi flash):

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 validazione, 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 la ricerca lazy (.key) per le traduzioni con scope della vista

Quando le tue chiavi di traduzione sono organizzate per 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 rinomini o sposti una vista, i percorsi della ricerca lazy si aggiornano automaticamente.

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

Per un'app reale, un unico en.yml gigante diventa ingestibile. 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 la ricerca lazy.
  • Interpolazione %{name} per le variabili inline.
  • Chiavi di pluralizzazione zero / one / other per i sostantivi 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 (alert, 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 tradurrai con PTC nella sezione successiva, queste stringhe viaggeranno con le altre.

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

Una volta pronti i file di traduzione, avrai bisogno delle versioni per ogni lingua di destinazione. PTC gestisce questo processo:

  1. Avvia un progetto PTC e scegli l'inglese come origine. La prova gratuita copre 20.000 parole in 2 lingue, senza 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 con i valori tradotti. Le forme plurali vengono generate per ogni lingua. Il polacco riceve one / few / many / other. Il giapponese riceve solo other.

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

Per i progetti basati su Git, punta PTC al tuo repository. Le nuove stringhe in qualsiasi *.en.yml attivano la traduzione automatica. PTC apre una pull request con i file delle lingue di destinazione aggiornati. Vedi i riferimenti API di PTC per il flusso di sincronizzazione.

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

Il pattern I18n.with_locale(locale, &block) è fondamentale per qualsiasi codice eseguito al di fuori di una normale richiesta. Questo include background job, 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 in qualunque lingua fosse attiva all'avvio del worker. Solitamente :en, indipendentemente dalla preferenza dell'utente. Con esso, l'email viene renderizzata nella lingua dell'utente e la lingua viene ripristinata al termine del blocco.

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

Le pagine renderizzate da Rails ricevono le traduzioni tramite t() in ERB. Il JavaScript eseguito nel browser non vede direttamente l'I18n di Rails. Il pattern più pulito utilizza la gemma i18n-js per esportare le traduzioni come 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.

Fissa 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 la lingua 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 utilizza le traduzioni corrette dall'attributo data-locale.

Traduci i contenuti di ActiveRecord con l'API di PTC

Il pattern sopra descritto traduce le stringhe statiche nei tuoi file YAML. I contenuti di ActiveRecord (post degli utenti, commenti, descrizioni dei prodotti memorizzate come input dell'utente) non appaiono nello YAML e richiedono un approccio diverso. L'API REST di PTC traduce questi contenuti su richiesta con autenticazione Bearer-token, utilizzando 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 una callback quando le traduzioni sono pronte o interroga lo stato da un background job.

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 gemma rails-i18n fornisce formati di data/ora predefiniti per molte lingue, inclusi i nomi dei mesi tradotti e la formattazione specifica per la lingua. Puoi definire formati personalizzati nei tuoi file YAML.

Numeri e valute. Rails include helper sensibili alla lingua:

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

Questi rispettano le convenzioni locali per i separatori decimali, i delimitatori delle migliaia e i simboli valuta.

Viste localizzate per lingua. Per pagine con contenuti significativamente diversi per lingua, crea file di vista separati. Rails renderizza la vista appropriata in base alla lingua 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 rilascio

Dopo che PTC ha tradotto i tuoi config/locales/*.yml, l'app Rails renderizzata ha comunque bisogno di una verifica. Un'etichetta tradotta potrebbe causare un overflow in un pulsante in tedesco. Un messaggio di validazione in francese potrebbe usare la forma grammaticale errata. Una stringa inglese hardcoded in un template ERB (senza chiamata a t()) verrà renderizzata non tradotta, indipendentemente da quante lingue rilasci.

AI Visual QA di PTC sostituisce il passaggio 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, cattura ogni schermata e segnala:

  • Correzioni nei file YAML quando PTC li controlla. PTC ri-traduce un senso errato, sceglie un sinonimo più breve, rigenera una forma plurale.
  • Prompt per Cursor / Claude Code quando il problema risiede nel tuo codice Ruby o ERB. Una stringa inglese hardcoded al di fuori di t(), un messaggio flash costruito per concatenazione invece che per interpolazione, un helper che dovrebbe usare I18n.l per la formattazione della data.

Il risultato: un'app Rails multilingue verificata a ogni rilascio. Non solo file YAML tradotti.

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 vivono al di fuori di config/locales. La funzione 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 utilizzano 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 gratuita di 30 giorni - 20.000 parole in 2 lingue, senza 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: