PTC

WordPress-Plugin-Übersetzungen werden nicht angezeigt? Fehlende Übersetzungen beheben

Fehlen Übersetzungen nach einem PTC-Durchlauf? Vier Prüfungen finden fast jede Ursache. Überprüfen Sie, ob der String PTC erreicht hat, ob der .mo-Dateiname mit den Erwartungen von WordPress übereinstimmt und ob die Text-Domain in Ihrem gesamten Code konsistent ist. Dieser Leitfaden führt Sie durch jede Prüfung in der Reihenfolge, in der sie durchgeführt werden sollten.

Dieselbe Diagnose-Reihenfolge funktioniert unabhängig davon, ob Sie mit PTC (Private Translation Cloud), GlotPress oder einem anderen Gettext-basierten Tool übersetzt haben. Die Fehlermodi sind in der WordPress-i18n-Pipeline begründet und hängen nicht von einem bestimmten Übersetzer ab.

Bestätigen Sie, dass der String PTC erreicht hat

Die erste Frage ist, ob der String in Ihrem PTC-Projekt vorhanden ist. Wenn ein String nicht in Ihre .pot-Datei extrahiert wurde, hat PTC ihn nie gesehen. Die .po-Datei enthält dann keine Übersetzung dafür. Das laufende Plugin zeigt als Fallback die Ausgangssprache an.

So prüfen Sie es:

  1. Öffnen Sie den betroffenen String im laufenden Plugin und kopieren Sie den exakten Text.
  2. Gehen Sie zu Ihrem PTC-Dashboard, öffnen Sie den Tab Translations und suchen Sie nach dem String.
  3. Wenn er dort nicht zu finden ist, hat PTC ihn nie erhalten.

Es folgen vier häufige Ursachen.

Ursache 1: Der String fehlt in Ihrer POT-Datei

wp i18n make-pot extrahiert nur Strings innerhalb der erkannten i18n-Funktionen. Das bedeutet __(), _e(), _n(), _x() und die escapten Varianten mit der richtigen Text-Domain. Strings innerhalb der falschen Domain werden übersprungen. Hardcodierte Strings außerhalb einer i18n-Funktion werden ebenfalls übersprungen.

Führen Sie die Extraktion erneut aus und verifizieren Sie, dass der String nun in der .pot enthalten ist:

wp i18n make-pot . languages/my-plugin.pot --domain=my-plugin
grep "Save Changes" languages/my-plugin.pot

Wenn grep den String mit einer msgid zurückgibt, funktioniert die Extraktion. Laden Sie die neue .pot erneut bei PTC hoch und übersetzen Sie sie neu. Wenn grep nichts zurückgibt, ist der String hardcodiert und nicht in __() eingeschlossen. Das ist Ihr Fehler. Schließen Sie den String ein und extrahieren Sie ihn erneut.

Ursache 2: Der Text ist nicht in eine Gettext-Funktion eingeschlossen

Jeder übersetzbare String in Ihrem Code benötigt einen Wrapper. Verwenden Sie __(), esc_html__(), _e(), _n() oder _x() mit der korrekten Text-Domain:

__( 'Hello, world!', 'your-plugin' );

Ursache 3: JavaScript-Strings wurden nicht als übersetzbar markiert

Wenn Ihr Plugin übersetzbaren Text in JavaScript enthält:

  1. Gehen Sie im PTC-Dashboard zu Settings > Monitored Files.
  2. Bearbeiten Sie die entsprechende Ressourcendatei und aktivieren Sie „Is this a WordPress project with localizable JavaScript?“

Dies weist PTC an, JavaScript-Dateien nach übersetzbaren Strings zu scannen. PTC generiert die Übersetzungen neu und öffnet einen neuen Merge Request mit den aktualisierten Dateien.

Stellen Sie dann sicher, dass WordPress weiß, wo die von PTC erzeugten .json-Übersetzungsdateien zu laden sind. Rufen Sie wp_set_script_translations() mit dem korrekten Pfad auf:

// For plugins
wp_set_script_translations(
    'script-handle',
    'text-domain',
    plugin_dir_path( __FILE__ ) . 'languages'
);

// For themes
wp_set_script_translations(
    'script-handle',
    'text-domain',
    get_template_directory() . '/languages'
);

Dies weist WordPress an, .json-Dateien aus Ihrem Plugin- oder Theme-Ordner zu laden.

Bestätigen Sie, dass WordPress Ihre .mo-Datei lädt

Wenn der String in PTC vorhanden ist und die .mo-Datei im languages/-Verzeichnis Ihres Plugins existiert, das gerenderte Plugin aber immer noch Englisch anzeigt, schlägt das Laden der .mo durch WordPress fehl.

Diagnose 1: Ist das Website-Locale korrekt eingestellt? Gehen Sie in wp-admin zu Einstellungen > Allgemein > Sprache der Website und bestätigen Sie, dass diese mit Ihrer Zielsprache übereinstimmt. Stellen Sie diese zum Testen der spanischen Übersetzung beispielsweise auf „Español“ ein. Wenn die Website auf Englisch eingestellt ist, wird Ihre spanische .mo niemals geladen. Dies ist kein Fehler.

Diagnose 2: Wird load_plugin_textdomain() tatsächlich ausgeführt? Fügen Sie eine temporäre Debug-Zeile hinzu:

add_action( 'init', function() {
    $loaded = load_plugin_textdomain(
        'my-plugin',
        false,
        dirname( plugin_basename( __FILE__ ) ) . '/languages'
    );
    error_log( 'my-plugin textdomain loaded: ' . var_export( $loaded, true ) );
} );

Laden Sie eine Seite neu und prüfen Sie Ihr PHP-Error-Log. loaded: true bedeutet, dass WordPress eine .mo-Datei für das aktuelle Locale gefunden und geladen hat. loaded: false bedeutet, dass dies nicht der Fall war. Die Ursache ist meist eine Nichtübereinstimmung des Dateinamens (siehe nächster Abschnitt) oder ein falscher Verzeichnispfad.

Diagnose 3: Stimmt das Hook-Timing? load_plugin_textdomain() muss am init-Hook ausgeführt werden. Dies ist der kanonische Hook, damit Übersetzungen auf Strings angewendet werden, die während der normalen Anfrageverarbeitung ausgegeben werden.

Diagnose 4: Werden Ihre gebündelten Dateien von Community-Übersetzungen überschrieben? Standardmäßig priorisiert WordPress Übersetzungsdateien, die in /wp-content/languages/ gespeichert sind. Wenn Ihr Plugin oder Theme über Community-Übersetzungen auf WordPress.org verfügt, können diese Dateien die mit Ihrem Projekt gebündelten .mo-Dateien überschreiben. Um dies zu verhindern, verwenden Sie den Filter load_textdomain_mofile, um das Laden Ihres gebündelten Dateipfads zu erzwingen, bevor WordPress das globale Verzeichnis prüft. Projekte mit mehreren Text-Domains (ein Plugin, das ein anderes Plugin einbettet) müssen jede Domain separat laden. Jede Domain benötigt ihren eigenen Aufruf von load_plugin_textdomain() oder load_theme_textdomain().

Stellen Sie sicher, dass der MO-Dateiname dem WordPress-Suchmuster entspricht

Die Suche nach .mo-Dateien in WordPress folgt einer strengen Namenskonvention. Schon eine Abweichung um ein einzelnes Zeichen führt dazu, dass WordPress lautlos auf Englisch zurückfällt.

Die Konvention hängt davon ab, wo Sie die Datei platzieren:

Ort Muster Beispiel
/languages/ des Plugins {text-domain}-{locale}.mo my-plugin-de_DE.mo
/languages/ des Themes {locale}.mo de_DE.mo
Globales Verz. (/wp-content/languages/...) {text-domain}-{locale}.mo my-theme-de_DE.mo

Einige praxisnahe Beispiele:

  • my-plugin-es_ES.mo für Spanisch (Spanien)
  • my-plugin-fr_FR.mo für Französisch (Frankreich)
  • my-plugin-pt_BR.mo für Portugiesisch (Brasilien)
  • my-plugin-zh_CN.mo für vereinfachtes Chinesisch
  • my-plugin-ja.mo für Japanisch (einige Locales haben kein Regions-Suffix)

Häufige Fehler:

  • Falscher Text-Domain-Präfix. Wenn der Text Domain-Header Ihres Plugins my-plugin lautet, die .mo aber myplugin-es_ES.mo heißt (fehlender Bindestrich), wird WordPress sie nicht finden. Der Präfix muss exakt mit dem Wert von Text Domain übereinstimmen.
  • Falscher Locale-Code. es.mo anstelle von es_ES.mo. WordPress verwendet regionale Locale-Codes. es_ES, es_MX und es_AR sind unterschiedliche Dateien. Ein reiner Sprachcode funktioniert nur, wenn keine regionale Datei existiert.
  • Bindestrich vs. Unterstrich. Locale-Codes verwenden einen Unterstrich (es_ES), niemals einen Bindestrich (es-ES). Dieser Fehler unterläuft Entwicklern oft, die Locale-Codes aus Browser-Accept-Language-Headern oder BCP 47-Quellen kopieren, wo der Bindestrich Standard ist.
  • Falsches Verzeichnis. Der Domain Path-Header muss auf das Verzeichnis zeigen, das Ihre .mo-Dateien enthält. Wenn der Domain Path /languages ist und Ihre .mo-Dateien in /lang/ liegen, wird WordPress sie nicht finden.

Prüfen Sie dies, indem Sie die von PTC erzeugten Dateien mit dem Locale abgleichen, das Ihre Website verwendet:

ls plugins/my-plugin/languages/
# my-plugin-es_ES.mo
# my-plugin-es_ES.po
# my-plugin-fr_FR.mo
# my-plugin-fr_FR.po

Wenn die Namen korrekt aussehen, die Übersetzungen aber dennoch nicht geladen werden, führen Sie die oben genannte Diagnose für load_plugin_textdomain() aus, um zu bestätigen, dass WordPress das Verzeichnis findet.

Prüfen Sie, ob Ihre Text-Domain im gesamten Code konsistent ist

Dies ist die lautlose Fehlerquelle. Jeder Aufruf von __(), _e(), _n(), _x() in Ihrem Code übergibt eine Text-Domain als letztes Argument. Wenn auch nur ein einziger Aufruf die falsche Domain übergibt, wird dieser eine String nicht übersetzt. Jeder andere String im Plugin wird einwandfrei funktionieren.

// Correct - matches the plugin's Text Domain
$correct = __( 'Save Changes', 'my-plugin' );

// Wrong - text domain typo; this string is never translated
$wrong = __( 'Save Changes', 'myplugin' );  // missing hyphen

// Wrong - copy-pasted from another plugin
$wrong = __( 'Save Changes', 'other-plugin' );

// Wrong - WordPress core domain; works for core strings but not yours
$wrong = __( 'Save Changes', 'default' );

Finden Sie Inkonsistenzen, indem Sie Ihre Codebasis per Grep durchsuchen:

grep -rE "__\(|_e\(|_n\(|_x\(" --include="*.php" .

Betrachten Sie das letzte Argument jedes Treffers. Sie sollten alle der Text-Domain Ihres Plugins entsprechen. Wenn Sie Tippfehler oder Copy-Paste-Fehler finden, beheben Sie diese und führen Sie wp i18n make-pot erneut aus, um die .pot zu aktualisieren.

Für JavaScript-Code, der @wordpress/i18n verwendet, gilt dieselbe Regel. wp_set_script_translations() in PHP muss ebenfalls die passende Domain übergeben:

wp_set_script_translations( 'my-plugin-editor', 'my-plugin', '...' );
//                                                ^^^^^^^^^^^
//                                                Must match the JS calls

Erkennen Sie dieselben Probleme vor der Veröffentlichung mit AI Visual QA

Die obige Diagnoseschleife ist reaktiv. Eine Übersetzung fehlt, und Sie begeben sich auf die Suche nach der Ursache. Die AI Visual QA von PTC erkennt dieselben Probleme, bevor sie veröffentlicht werden. Sie prüft das gerenderte Plugin in jeder Zielsprache nach jedem Übersetzungs-Update und meldet zurück, was fehlt oder falsch ist.

Bei einem hardcodierten englischen String außerhalb von __() (Ursache 1 oben) erkennt AI Visual QA den unübersetzten String im gerenderten Produkt. PTC generiert einen kopierfertigen Prompt für Cursor oder Claude Code, um den String in __() einzuschließen. Bei einer Nichtübereinstimmung der Text-Domain (die Prüfung im vorherigen Abschnitt) erkennt das System den unübersetzten String, während andere Strings auf demselben Bildschirm übersetzt sind, und meldet die Inkonsistenz.

Wenn Sie AI Visual QA noch nicht aktiviert haben, finden Sie Informationen zur Einrichtung im Tutorial für WordPress-Themes und -Plugins.

Wenn alle vier Prüfungen durchgeführt wurden und Übersetzungen immer noch fehlen

Wenn Sie alle vier Prüfungen durchgeführt haben und die Übersetzungen immer noch nicht angezeigt werden, senden Sie eine E-Mail an den PTC-Support mit folgenden Informationen:

  • Der Text-Domain Ihres Plugins.
  • Einem der .mo-Dateinamen (z. B. my-plugin-es_ES.mo).
  • Einem Screenshot des PTC-Dashboards, der den betroffenen String mit seiner Übersetzung zeigt.
  • Der Einstellung der Website-Sprache unter Einstellungen > Allgemein.

Die meisten Fälle von „fehlenden Übersetzungen“ lassen sich auf eine der oben genannten Ursachen zurückführen. Sonderfälle (spezifische WordPress-Versionen, MultiSite-Locale-Auflösung, Konflikte mit einem anderen i18n-Plugin) erfordern manchmal eine genauere Untersuchung.

Zukünftige Releases mit kontinuierlicher Lokalisierung synchron halten

Sobald Ihre Übersetzungen korrekt geladen werden, richten Sie den Workflow für kontinuierliche Lokalisierung ein, damit zukünftige Releases mit Ihren Übersetzungen synchron bleiben – automatisch bei jedem Push auf den Main-Branch.