PTC

Rails-Internationalisierung (i18n): Der vollständige Leitfaden

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 verfügen Sie über eine Rails-App, die auf /es/...-URLs reagiert, übersetzte Views in über 40 Sprachen bereitstellt und durch eine visuelle Prüfung verifiziert ist.

Dieser Leitfaden setzt voraus, dass Sie eine bestehende 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. Informationen zur umfassenderen CI/CD-Lokalisierung über verschiedene Stacks hinweg finden Sie unter KI-Software-Lokalisierung für CI/CD-Pipelines.

Rails konfigurieren: Locales laden, URLs erkennen und pro Request umschalten

Die Rails-Internationalisierung erfordert drei Konfigurationsschritte. Legen Sie die verfügbaren Locales fest, fügen Sie das Locale zu Ihren URLs hinzu und lassen Sie Rails das korrekte Locale pro Request laden. Zudem installieren Sie das Gem rails-i18n für die Locale-Daten.

Verfügbare Locales in config/application.rb deklarieren

Geben Sie in config/application.rb an, welche Sprachen die App unterstützt, und legen Sie einen Standard 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 entscheidend. Standardmäßig lädt Rails nur config/locales/*.yml (eine Ebene tief). Durch das Hinzufügen des rekursiven Globs können Sie Übersetzungen nach Namespace, Model oder Feature in Unterverzeichnissen organisieren.

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

Fügen Sie einen :locale-Scope hinzu, damit jede Sprache ihren eigenen Pfad hat, wie /en/time oder /de/time:

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

Locale pro Request mit I18n.with_locale umschalten

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

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 der idiomatische Weg, um ein Locale auf einen Request zu begrenzen. Es setzt das Locale, führt den Block aus, stellt das vorherige Locale wieder her und ist threadsicher. default_url_options stellt sicher, dass jede von Rails generierte URL das aktuelle Locale enthält, damit Benutzer beim Navigieren in der gewählten Sprache bleiben.

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

Das Gem rails-i18n liefert Locale-Daten für Dutzende von Sprachen. Dieses Gem enthält übersetzte Monatsnamen, Pluralisierungsregeln und Standard-Fehlermeldungen von Rails. So müssen Sie diesen Standardtext nicht selbst übersetzen.

# Gemfile
gem 'rails-i18n'
bundle install

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

Einen Sprachumschalter mit url_for(locale: :code) hinzufügen

Da default_url_options das Locale automatisch in jede generierte URL einfügt, muss Ihr Umschalter lediglich den Parameter :locale aktualisieren, während der Benutzer auf derselben Seite bleibt.

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

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

Hardcodierten Text in Views durch t(:key) ersetzen

Hardcodierter Text erscheint nicht in Ihren YAML-Dateien, was bedeutet, dass er nicht übersetzt werden kann. Verwenden Sie für alle für Benutzer sichtbaren Texte 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-Meldungen):

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 Models (verwenden Sie für Validierungsmeldungen die Active Model-Konventionen):

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

Variablen mit %{name} interpolieren

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

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

Lazy Lookup (.key) für View-bezogene Übersetzungen verwenden

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 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, werden die Lazy-Lookup-Pfade automatisch aktualisiert.

config/locales/ nach Features organisieren statt einer riesigen en.yml

In einer echten App wird eine einzige riesige en.yml unübersichtlich. Organisieren Sie diese 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 zusammengehörige Strings und ermöglichen Lazy Lookup.
  • %{name}-Interpolation für Inline-Variablen.
  • zero / one / other Pluralisierungs-Schlüssel für zählbare Substantive. Rails leitet basierend auf count: zum richtigen Schlüssel weiter: t('posts.show.comments_count', count: 5).

JavaScript-Strings ebenfalls zum YAML hinzufügen

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

en:
  confirm: "Are you sure?"

Wenn Sie im nächsten Abschnitt mit PTC übersetzen, werden diese Strings zusammen mit den restlichen übertragen.

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

Sobald Ihre Übersetzungsdateien vorhanden sind, benötigen Sie Versionen für jede Zielsprache. PTC übernimmt dies:

  1. Starten Sie ein PTC-Projekt und wählen Sie Englisch als Ausgangssprache. Die kostenlose Testphase deckt 20.000 Wörter in 2 Sprachen ab, keine Kreditkarte erforderlich.
  2. Laden Sie Ihre config/locales/*.en.yml-Dateien hoch. PTC parst das 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 Zielgruppe hinzu. PTC nutzt diesen Kontext, um mit der richtigen Tonalität und Terminologie zu übersetzen.
  4. Wählen Sie die Zielsprachen aus und bestätigen Sie. PTC erstellt posts.es.yml, posts.fr.yml, posts.de.yml, die strukturell identisch mit der Quelle sind, aber übersetzte Werte enthalten. Pluralformen werden pro Sprache generiert. Polnisch erhält one / few / many / other. Japanisch erhält nur other.

Kopieren Sie die Dateien zurück nach config/locales/views/, starten Sie Ihren Rails-Server neu, und die App stellt die neuen Sprachen bereit.

Bei Git-gesteuerten Projekten verknüpfen Sie PTC mit Ihrem Repository. Neue Strings in einer beliebigen *.en.yml lösen eine automatische Übersetzung aus. PTC öffnet einen Pull Request mit den aktualisierten Zielsprachdateien. Den Synchronisations-Flow finden Sie in der PTC API-Referenz.

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

Das Muster I18n.with_locale(locale, &block) ist entscheidend für jeden Code, der außerhalb eines normalen Requests läuft. Dazu gehören Background-Jobs, Cron-Tasks und 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 beim Start des Workers aktiv war. Meistens ist dies :en, unabhängig von der Präferenz des Benutzers. Mit dieser Methode wird die E-Mail in der Sprache des Benutzers gerendert und das Locale wird nach Abschluss des Blocks zurückgesetzt.

Rails-Übersetzungen mit i18n-js für die clientseitige Nutzung nach JSON exportieren

Von Rails gerenderte Seiten erhalten Übersetzungen über t() in ERB. JavaScript, das im Browser läuft, sieht das I18n von Rails nicht direkt. Das sauberste Muster verwendet das Gem i18n-js, 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 für 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 den <body>-Tag an JavaScript:

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

Verwenden Sie dann die Übersetzungen 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 Benutzer die Sprache wechseln, verwendet JavaScript die korrekten Übersetzungen aus dem Attribut data-locale.

ActiveRecord-Inhalte mit der PTC API übersetzen

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

Datum, Zahlen und Währung mit Rails-Helpern lokalisieren

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

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

Das Gem rails-i18n bietet Standardformate für Datum und Uhrzeit für viele Sprachen, einschließlich übersetzter Monatsnamen und lokaler Formatierung. Sie können in Ihren YAML-Dateien benutzerdefinierte Formate definieren.

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

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

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

Lokalisierte Views pro Sprache. Erstellen Sie für Seiten mit deutlich unterschiedlichem Inhalt pro Locale separate View-Dateien. Rails rendert die entsprechende 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 – Release ohne manuelle QA pro Release

Nachdem PTC Ihre config/locales/*.yml übersetzt hat, muss die gerenderte Rails-App noch verifiziert werden. Ein übersetztes Label könnte auf Deutsch über die Grenzen eines Buttons hinausragen (Überlauf). Eine französische Validierungsmeldung könnte die falsche grammatikalische Form verwenden. Ein hardcodierter englischer String in einem ERB-Template (ohne t()-Aufruf) wird unübersetzt gerendert, egal in wie viele Sprachen Sie übersetzen.

Die AI Visual QA von PTC ersetzt den manuellen QA-Durchgang. Installieren Sie für Rails-Apps (browserbasiert) die PTC Browser-Erweiterung und zeichnen Sie einen Rundgang durch die kritischen Bildschirme Ihrer App auf (Anmeldung, Haupt-Flows, Admin-Seiten). Von da an spielt PTC die Aufzeichnung nach jedem Übersetzungs-Update in jeder Zielsprache ab, erfasst jeden Bildschirm und meldet zurück:

  • Korrekturen in den YAML-Dateien, wenn PTC diese kontrolliert. PTC korrigiert Fehlübersetzungen, wählt ein kürzeres Synonym oder generiert eine Pluralform neu.
  • Cursor / Claude Code Prompts, wenn das Problem in Ihrem Ruby- oder ERB-Code liegt. Ein hardcodierter englischer String außerhalb von t(), eine Flash-Meldung, die durch Konkatenation statt Interpolation erstellt wurde, oder ein Helper, der I18n.l für die Datumsformatierung verwenden sollte.

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

Release Notes, Devise-Mailer und Marketing-Seiten übersetzen

Ihre Release Notes, kundenorientierte E-Mails, die über Devise oder Action Mailer versendet werden, und Marketing-Seiten befinden sich außerhalb von config/locales. Die Funktion Paste to Translate von PTC verarbeitet diese Texte im selben Projekt. Fügen Sie den Ausgangstext im PTC-Dashboard ein, wählen Sie die Zielsprachen aus und erhalten Sie Übersetzungen zurück, 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-Tage-Testphase – 20.000 Wörter in 2 Sprachen, keine Kreditkarte erforderlich. Laden Sie Ihre YAML-Dateien hoch, erhalten Sie in wenigen Minuten übersetzte Versionen und installieren Sie dann die Browser-Erweiterung, um Ihre laufende Rails-App zu verifizieren.

Verwandte Themen: