PTC

Rails-Internationalisierung (i18n): Vollständige Anleitung

Konfigurieren Sie Rails I18n, organisieren Sie config/locales/*.yml, automatisieren Sie YAML-Übersetzungen mit KI und lassen Sie PTC (Private Translation Cloud) Ihre laufende Rails-App bei jedem Release prüfen. Am Ende haben Sie eine Rails-App, die auf /es/...-URLs reagiert, übersetzte Views in über 40 Sprachen ausliefert und durch visuelle Prüfung verifiziert ist.

Diese Anleitung setzt voraus, dass Sie bereits eine Rails-7+-App haben. Die Konzepte gelten mit geringfügigen API-Unterschieden auch für ältere Rails-Versionen. Das I18n-Gem selbst ist seit Jahren stabil. Die umfassendere CI/CD-Lokalisierungsgeschichte über verschiedene Stacks hinweg finden Sie unter KI-Softwarelokalisierung für CI/CD-Pipelines.

Konfigurieren Sie Rails so, dass es Locales lädt, URLs erkennt und pro Anfrage wechselt

Die Rails-Internationalisierung erfordert drei Konfigurationsschritte. Legen Sie die verfügbaren Locales fest, fügen Sie das Locale zu Ihren URLs hinzu und sorgen Sie dafür, dass Rails das richtige Locale pro Anfrage lädt. Außerdem installieren Sie das rails-i18n-Gem für die Locale-Daten.

Deklarieren Sie verfügbare Locales in config/application.rb

Teilen Sie Rails in config/application.rb mit, welche Sprachen die App unterstützt, und legen Sie eine Standardsprache fest:

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

Die Zeile load_path += Dir[...] ist die entscheidende. Standardmäßig lädt Rails nur config/locales/*.yml (eine Ebene tief). Durch Hinzufügen des rekursiven Glob können Sie Übersetzungen nach Namespace, Modell oder Feature in Unterverzeichnissen organisieren.

Fügen Sie :locale zu Ihrem URL-Scope hinzu

Fügen Sie einen :locale-Scope hinzu, sodass jede Sprache ihren eigenen Pfad hat, etwa /en/time oder /es/time:

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

Wechseln Sie das Locale pro Anfrage mit I18n.with_locale

Laden Sie im ApplicationController das richtige Locale aus der URL und nehmen Sie es in alle generierten Links auf:

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 ist die idiomatische Art, ein Locale auf eine Anfrage zu beschränken. Es setzt das Locale, führt den Block aus, stellt das vorherige Locale wieder her und ist thread-sicher. default_url_options stellt sicher, dass jede von Rails generierte URL das aktuelle Locale trägt, sodass Nutzer beim Navigieren in ihrer gewählten Sprache bleiben.

Installieren Sie rails-i18n für übersetzte Monatsnamen und Pluralisierungsregeln

Das rails-i18n-Gem stellt Locale-Daten für Dutzende von Sprachen bereit. Übersetzte Monatsnamen, Pluralisierungsregeln, standardmäßige Rails-Fehlermeldungen. So müssen Sie diesen Boilerplate-Code nicht selbst übersetzen.

# Gemfile
gem 'rails-i18n'
bundle install

Ihre Rails-App ist nun vollständig für die Internationalisierung konfiguriert.

Fügen Sie mit url_for(locale: :code) einen Sprachumschalter hinzu

Da default_url_options das Locale automatisch in jede generierte URL aufnimmt, muss Ihr Umschalter nur den :locale-Parameter aktualisieren und den Nutzer dabei auf derselben Seite halten.

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

Jeder Link verwendet url_for(locale: :code), um eine URL mit dem angegebenen Locale zu generieren. Wenn Nutzer klicken, erkennt switch_locale im ApplicationController die Änderung und Rails rendert die Seite in der neuen Sprache.

Ersetzen Sie fest codierten Text in Views durch t(:key)

Fest codierter Text erscheint nicht in Ihren YAML-Dateien, was bedeutet, dass er nicht übersetzt werden kann. Verwenden Sie für jeden für Nutzer sichtbaren Text immer Übersetzungsschlüssel.

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

In Controllern (für Flash-Nachrichten):

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

In Modellen (für Validierungsmeldungen, verwenden Sie die Active-Model-Konventionen):

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

Interpolieren Sie Variablen mit %{name}

%{name} in der YAML wird durch den Wert ersetzt, den Sie an t() übergeben:

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

Verwenden Sie Lazy Lookup (.key) für view-bezogene Übersetzungen

Wenn Ihre Übersetzungsschlüssel so organisiert sind, dass sie Ihrer View-Ordnerstruktur entsprechen, verwenden Sie einen führenden Punkt. Rails ergänzt das Präfix aus der aktuellen View:

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

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

Rails erkennt, dass Sie sich in home/index.html.erb befinden, und stellt home.index. voran. Wenn Sie eine View umbenennen oder verschieben, aktualisieren sich die Lazy-Lookup-Pfade automatisch.

Organisieren Sie config/locales/ nach Feature statt in einer riesigen en.yml

Für eine reale App wird eine einzige riesige en.yml unwartbar. Organisieren Sie pro Feature:

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

Ein Beispiel für 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"

Konventionen:

  • Verschachtelte Schlüssel gruppieren verwandte Strings und ermöglichen Lazy Lookup.
  • %{name}-Interpolation für Inline-Variablen.
  • zero / one / other-Pluralisierungsschlüssel für zählbare Substantive. Rails wählt anhand von count: den richtigen Schlüssel: t('posts.show.comments_count', count: 5).

Fügen Sie JavaScript-Strings ebenfalls zur YAML hinzu

Rails extrahiert Text aus JavaScript-Dateien nicht automatisch. Jeder clientseitige Text (Alerts, Tooltips, Bestätigungsmeldungen) muss in Ihrer YAML stehen, damit er zusammen mit allem anderen übersetzt wird:

en:
  confirm: "Are you sure?"

Wenn Sie im nächsten Abschnitt mit PTC übersetzen, reisen diese Strings mit dem Rest mit.

Übersetzen Sie config/locales/*.en.yml mit PTC in 4 Schritten

Sobald Ihre Übersetzungsdateien vorliegen, benötigen Sie Versionen für jede Zielsprache. PTC übernimmt das:

  1. Starten Sie ein PTC-Projekt und wählen Sie Englisch als Quelle. Die kostenlose Testphase umfasst 20.000 Wörter in 2 Sprachen, ohne Kreditkarte.
  2. Laden Sie Ihre config/locales/*.en.yml-Dateien hoch. PTC parst die YAML, erkennt Rails-Pluralisierungsschlüssel (zero, one, other, few, many) und bewahrt %{name}-Interpolationen.
  3. Fügen Sie eine kurze Beschreibung Ihrer Rails-App und Ihrer Zielgruppe hinzu. PTC nutzt diesen Kontext, um mit dem richtigen Ton und der richtigen Terminologie zu übersetzen.
  4. Wählen Sie Zielsprachen und bestätigen Sie. PTC erzeugt posts.es.yml, posts.fr.yml, posts.de.yml, strukturell identisch mit der Quelle, jedoch mit übersetzten Werten. Pluralformen werden pro Sprache generiert. Polnisch erhält one / few / many / other. Japanisch erhält nur other.

Legen Sie die Dateien zurück in config/locales/views/, starten Sie Ihren Rails-Server neu, und die App liefert die neuen Sprachen aus.

Für Git-gesteuerte Projekte verbinden Sie PTC mit Ihrem Repo. Neue Strings in einer beliebigen *.en.yml lösen eine automatische Übersetzung aus. PTC öffnet einen PR mit den aktualisierten zielsprachigen Dateien. Den Synchronisationsablauf finden Sie in der PTC-API-Referenz.

Verwenden Sie I18n.with_locale in Background Jobs, Mailern und Cron-Tasks

Das Muster I18n.with_locale(locale, &block) ist für jeden Code unverzichtbar, der außerhalb einer normalen Anfrage läuft. Background Jobs, Cron-Tasks, 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

Ohne with_locale läuft der Job in dem Locale, das aktiv war, als der Worker startete. Üblicherweise :en, unabhängig von der Präferenz des Nutzers. Mit ihm wird die E-Mail in der Sprache des Nutzers gerendert und das Locale zurückgesetzt, sobald der Block endet.

Exportieren Sie Rails-Übersetzungen mit i18n-js als JSON für die clientseitige Nutzung

Von Rails gerenderte Seiten erhalten Übersetzungen über t() in ERB. JavaScript, das im Browser läuft, sieht Rails' I18n nicht direkt. Das sauberste Muster nutzt das i18n-js-Gem, um Übersetzungen als JSON zu exportieren und sie clientseitig zu laden.

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

Aktualisieren Sie die generierte Konfiguration, um Übersetzungen nach public/locales.json zu exportieren:

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

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

Generieren Sie die JSON-Datei:

i18n export

Dies liest alle Ihre YAML-Dateien (en.yml, es.yml, de.yml) und schreibt public/locales.json mit jeder Übersetzung in einem JS-lesbaren Format.

Pinnen Sie i18n-js mit Rails 7+ Importmap:

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

Erstellen Sie einen Loader:

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

Übergeben Sie das aktuelle Locale über das <body>-Tag an JavaScript:

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

Verwenden Sie die Übersetzungen dann in Ihrem 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() funktioniert wie der t-Helper von Rails. Wenn Nutzer die Sprache wechseln, verwendet JavaScript die korrekten Übersetzungen aus dem data-locale-Attribut.

Übersetzen Sie ActiveRecord-Inhalte mit der PTC-API

Das obige Muster übersetzt statische Strings in Ihren YAML-Dateien. ActiveRecord-Inhalte (Nutzerbeiträge, Kommentare, Produktbeschreibungen, die als Nutzereingaben gespeichert sind) erscheinen nicht in der YAML und benötigen einen anderen Ansatz. Die PTC-REST-API übersetzt diese Inhalte bei Bedarf mit Bearer-Token-Authentifizierung und verwendet dasselbe Glossar und dieselbe Markenstimme wie Ihre config/locales/*.yml-Dateien. Senden Sie Ihre Inhalte per POST an PTC und erhalten Sie dann entweder einen Callback, wenn die Übersetzungen fertig sind, oder fragen Sie den Status aus einem Background Job ab.

Lokalisieren Sie Datumsangaben, Zahlen und Währungen mit Rails-Helpern

Datums- und Zeitangaben. Verwenden Sie den l-Helper (kurz für localize):

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

Das rails-i18n-Gem stellt Standard-Datums-/Zeitformate für viele Sprachen bereit, einschließlich übersetzter Monatsnamen und locale-spezifischer Formatierung. Sie können benutzerdefinierte Formate in Ihren YAML-Dateien definieren.

Zahlen und Währung. Rails enthält locale-bewusste Helper:

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

Diese respektieren die Locale-Konventionen für Dezimaltrennzeichen, Tausendertrennzeichen und Währungssymbole.

Lokalisierte Views pro Sprache. Für Seiten mit deutlich unterschiedlichen Inhalten pro Locale erstellen Sie separate View-Dateien. Rails rendert die passende View basierend auf dem aktuellen Locale:

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

Visuelle Übersetzungsprüfung Ihrer laufenden Rails-App - releasen ohne manuelle QA pro Release

Nachdem PTC Ihre config/locales/*.yml übersetzt hat, benötigt die gerenderte Rails-App noch eine Verifizierung. Ein übersetztes Label kann auf Deutsch über einen Button hinauslaufen. Eine französische Validierungsmeldung kann die falsche grammatikalische Form verwenden. Ein fest codierter englischer String in einem ERB-Template (ohne t()-Aufruf) wird untranslatiert gerendert, egal wie viele Sprachen Sie ausliefern.

Die visuelle KI-Prüfung von PTC ersetzt den manuellen QA-Durchgang. Für Rails-Apps (browserbasiert) installieren Sie die PTC-Browser-Erweiterung und zeichnen Sie einen Durchlauf der kritischen Bildschirme Ihrer App auf (Anmeldung, Hauptabläufe, Admin-Seiten). Von da an spielt PTC die Aufzeichnung nach jeder Übersetzungsaktualisierung in jeder Zielsprache erneut ab, erfasst jeden Bildschirm und meldet zurück:

  • Korrekturen in den YAML-Dateien, wenn PTC sie kontrolliert. PTC übersetzt einen falschen Sinn neu, wählt ein kürzeres Synonym, generiert eine Pluralform neu.
  • Cursor- / Claude-Code-Prompts, wenn das Problem in Ihrem Ruby- oder ERB-Code liegt. Ein fest codierter englischer String außerhalb von t(), eine Flash-Nachricht, die durch Verkettung statt durch Interpolation erstellt wird, ein Helper, der I18n.l für die Datumsformatierung verwenden sollte.

Das Ergebnis: eine verifizierte mehrsprachige Rails-App pro Release. Nicht nur übersetzte YAML.

Übersetzen Sie Release Notes, Devise-Mailer und Marketing-Seiten

Ihre Release Notes, kundenseitigen E-Mails, die über Devise oder Action Mailer versendet werden, und Marketing-Seiten liegen außerhalb von config/locales. Die Funktion Paste to Translate von PTC verarbeitet diese Texte im selben Projekt. Fügen Sie den Quelltext im PTC-Dashboard ein, wählen Sie Zielsprachen und erhalten Sie Übersetzungen, die dasselbe Glossar und dieselbe Markenstimme wie Ihre YAML-Übersetzungen verwenden.

Übersetzen Sie Ihre config/locales/*.yml-Dateien mit PTC

Starten Sie Ihre kostenlose 30-tägige Testphase - 20.000 Wörter in 2 Sprachen, ohne Kreditkarte. Laden Sie Ihre YAML-Dateien hoch, erhalten Sie übersetzte Versionen in Minuten und installieren Sie dann die Browser-Erweiterung, um Ihre laufende Rails-App zu verifizieren.

Verwandt: