PTC

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

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

Dieselbe Diagnose-Reihenfolge funktioniert, unabhängig davon, ob Sie mit der PTC (Private Translation Cloud), GlotPress oder einem anderen gettext-basierten Tool übersetzt haben. Die Fehlerquellen sind der WordPress-i18n-Pipeline inhärent und liegen nicht an einem bestimmten Übersetzer.

Bestätigen Sie, dass der String die PTC erreicht hat

Die erste Frage ist, ob sich der String in Ihrem PTC-Projekt befindet. Wenn ein String nicht in Ihre .pot-Datei extrahiert wurde, hat die PTC ihn nie gesehen. Die .po-Datei enthält keine Übersetzung dafür. Das ausgeführte Plugin zeigt den Ausgangssprachen-Fallback an.

So prüfen Sie das:

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

Es folgen drei 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 escaped Varianten, mit der richtigen Text Domain. Strings in der falschen Domain werden übersprungen. Hardcodierte Strings außerhalb einer i18n-Funktion werden übersprungen.

Führen Sie die Extraktion erneut aus und überprüfen Sie, ob der String nun in der .pot ist:

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

Wenn grep den String mit einem msgid zurückgibt, funktioniert die Extraktion. Laden Sie die neue .pot erneut in die PTC hoch und übersetzen Sie sie neu. Wenn grep nichts zurückgibt, ist der String hardcodiert und nicht in __() gewrappt. Das ist Ihr Fehler. Wrappen Sie den String und extrahieren Sie ihn neu.

Ursache 2: Der Text ist nicht in eine gettext-Funktion gewrappt

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 Einstellungen > Überwachte Dateien.
  2. Bearbeiten Sie die entsprechende Ressourcendatei und aktivieren Sie „Is this a WordPress project with localizable JavaScript?“

Dies weist die PTC an, JavaScript-Dateien nach übersetzbaren Strings zu scannen. Die 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 der PTC erstellten .json-Übersetzungsdateien geladen werden sollen. 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 der PTC vorhanden ist und die .mo-Datei im languages/-Verzeichnis Ihres Plugins existiert, das gerenderte Plugin aber weiterhin Englisch anzeigt, kann WordPress die .mo nicht laden.

Diagnose 1: Ist die Locale der Website korrekt eingestellt? Gehen Sie in wp-admin zu Einstellungen > Allgemein > Sprache der Website und bestätigen Sie, dass sie mit Ihrer Zielsprache übereinstimmt. Stellen Sie sie zum Beispiel auf „Español“, um Spanisch zu testen. Wenn die Website auf Englisch ist, wird Ihre spanische .mo niemals geladen. Das 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-Fehlerprotokoll. loaded: true bedeutet, dass WordPress eine .mo-Datei für die aktuelle Locale gefunden und geladen hat. loaded: false bedeutet, dass dies nicht der Fall ist. Die Ursache ist meist ein nicht übereinstimmender Dateiname (siehe nächster Abschnitt) oder ein falscher Verzeichnispfad.

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

Diagnose 4: Überschreiben Community-Übersetzungen Ihre gebündelten Dateien? Standardmäßig priorisiert WordPress Übersetzungsdateien, die in /wp-content/languages/ gespeichert sind. Wenn Ihr Plugin oder Theme von der Community bereitgestellte Übersetzungen auf WordPress.org hat, können diese Dateien die mit Ihrem Projekt gebündelten .mo-Dateien überschreiben. Um dies zu verhindern, verwenden Sie den load_textdomain_mofile-Filter, 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 load_plugin_textdomain()- oder load_theme_textdomain()-Aufruf.

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

Die .mo-Dateisuche von WordPress folgt einer strengen Namenskonvention. Schon bei einer Abweichung von einem Zeichen fällt WordPress stillschweigend auf Englisch zurück.

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

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

Einige praktische 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 Chinesisch (vereinfacht)
  • my-plugin-ja.mo für Japanisch (einige Locales haben kein Regionssuffix)

Häufige Fehler:

  • Falsches Text-Domain-Präfix. Wenn der Text Domain-Header Ihres Plugins my-plugin lautet, die .mo aber myplugin-es_ES.mo heißt (kein Bindestrich), wird WordPress sie nicht finden. Das Präfix muss exakt mit dem Text Domain-Wert übereinstimmen.
  • Falscher Locale-Code. es.mo statt es_ES.mo. WordPress verwendet regionale Locale-Codes. es_ES, es_MX und es_AR sind unterschiedliche Dateien. Ein bloßer Sprachcode funktioniert nur, wenn keine regionale Datei existiert.
  • Bindestrich vs. Unterstrich. Locale-Codes verwenden einen Unterstrich (es_ES), niemals einen Bindestrich (es-ES). Dies ist eine Stolperfalle für Entwickler, die Locale-Codes aus Accept-Language-Headern des Browsers 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 Domain Path auf /languages lautet und sich Ihre .mo-Dateien in /lang/ befinden, wird WordPress sie nicht finden.

Prüfen Sie dies, indem Sie die von der PTC erstellten Dateien mit der Locale abgleichen, die 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 richtig aussehen, die Übersetzungen aber immer noch nicht geladen werden, führen Sie die obige load_plugin_textdomain()-Diagnose aus, um zu bestätigen, dass WordPress das Verzeichnis findet.

Prüfen Sie, ob Ihre Text Domain in Ihrem Code konsistent ist

Das ist der unsichtbare Fehlerteufel. Jeder __()-, _e()-, _n()-, _x()-Aufruf in Ihrem Code übergibt eine Text Domain als letztes Argument. Wenn auch nur ein Aufruf die falsche Domain übergibt, wird dieser eine String nicht übersetzt. Jeder andere String im Plugin funktioniert problemlos.

// 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 mit grep durchsuchen:

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

Sehen Sie sich das letzte Argument jedes Treffers an. Sie sollten alle die Text Domain Ihres Plugins sein. Wenn Sie Tipp- 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 Fehler vor der Veröffentlichung mit der AI Visual QA

Die obige Diagnoseschleife ist reaktiv. Eine Übersetzung fehlt, Sie begeben sich auf die Suche nach der Ursache. Die AI Visual QA der PTC erkennt dieselben Fehler, 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) sieht die AI Visual QA den unübersetzten String im gerenderten Plugin. Die PTC generiert einen einsatzbereiten Prompt für den Cursor oder Claude Code, um den String in __() zu wrappen. Bei einer nicht übereinstimmenden Text Domain (Prüfung im vorherigen Abschnitt) sieht sie den String unübersetzt, während andere Strings auf demselben Bildschirm übersetzt sind, und meldet die Inkonsistenz.

Wenn Sie die AI Visual QA noch nicht aktiviert haben, lesen Sie das Tutorial für WordPress-Themes und -Plugins zur Einrichtung.

Wenn alle vier Prüfungen erfolgreich sind 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:

  • 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 für die Sprache der Website unter Einstellungen > Allgemein.

Die meisten Fälle von „fehlenden Übersetzungen“ lassen sich auf eine der obigen Ursachen zurückführen. Edge-Cases (bestimmte WordPress-Versionen, MultiSite-Locale-Auflösung, Konflikt mit einem anderen i18n-Plugin) erfordern manchmal einen zweiten Blick.

Halten Sie zukünftige Releases mit kontinuierlicher Lokalisierung synchron

Sobald Ihre Übersetzungen korrekt geladen werden, richten Sie den Workflow der kontinuierlichen Lokalisierung ein, damit zukünftige Releases mit Ihren Übersetzungen synchron bleiben – automatisch bei jedem Push zu main.