Fehlerhafte Plugin-Übersetzung in WPML reparieren

Letzte Woche hatte ich in einem Projekt ein Problem, bei dem für ein Plugin nicht die richtige Sprache geladen wurde. Es war ein mehrsprachiges Projekt mit drei Sprachen. Die Standardsprache war Deutsch, eine der beiden anderen war Englisch. Wenn es Probleme beim Laden von Übersetzungen gibt, wird ja normalerweise immer nur der englische Originaltext angezeigt. Nicht so in diesem Fall. Alle Texte waren in der Standardsprache Deutsch zu sehen, selbst auf der englischen Seite.

Das Projekt verwendete WPML für die Übersetzung der Inhalte. Für alle anderen Plugins, das Theme und die Inhalte, wurde immer die korrekte Sprache angezeigt. Nur eben nicht für dieses eine Plugin. Den Fehler zu finden war gar nicht einfach. Nachdem ich ihn dann aber ausgemacht hatte, war die Lösung schnell gefunden.

Der fehlerhafte Code

Vor zwei Jahren habe ich auf dem WordCamp Berlin 2015 einen Vortrag über die korrekte Initialisierung eines Plugins gehalten. Ich hatte damals ein ähnliches Problem mit einer nicht geladenen Übersetzung, allerdings wurden damals immer die englischen Strings angezeigt.

<?php
/**
 * Plugin Name: Broken Plugin
 */

# Load translation files.
load_plugin_textdomain( 'broken-plugin', false, 'broken-plugin/languages' );

# Initialize plugin.
add_action( 'after_setup_theme', 'broken_plugin_theme_setup', 12 );

function broken_plugin_theme_setup() {
	// Some code ...
}

Ich möchte jetzt nicht den Plugin-Autoren schlecht machen und habe daher den Namen anonymisiert. Oben seht ihr aber den Code, so wie er im Plugin vorkommt. Wie ihr sehen könnt, wird die Sprachdatei zu beginn der Plugin-Datei geladen. Das Plugin hat eine Callback-Funktion auf den Hook after_setup_theme, welcher perfekt für das Laden der Übersetzung wäre.

Der Grund für den Fehler

Aber wieso wird die Übersetzung nicht richtig geladen? Wie ich euch zu Beginn schon gesagt habe, sieht es ja eigentlich so aus, als würden Übersetzungen geladen werden. Andernfalls müssten ja alle Strings immer in Englisch sein und nicht immer in der Standardsprache Deutsch. Der Grund ist recht einfach. Das Plugin beginnt mit dem Buchstaben B (nicht nur das hier anonymisierte, sondern auch das echte Plugin) und da Plugins in alphabetischer Reihenfolge geladen werden und der Ordnername von WPML „sitepress-multilingual-cms“ ist, kommt der Code einfach zu früh. Der Wechsel zur korrekten Sprache passiert in WPML einfach erst dann, wenn es selbst komplett geladen wurde. Zu diesem Zeitpunkt wurde aber schon die falsche Sprachdatei geladen (Deutsch) und somit werden die Strings nicht mehr mit den richtigen ersetzt.

Das Plugin reparieren

Eine Lösung ist ja recht einfach. Wir verschieben einfach den Funktionsaufruf in die passende Callback-Finktion. Richtig? Das würde natürlich funktionieren, allerdings nur bis zum nächsten Plugin-Update. Dann wäre unser Fix wieder weg.

Wie machen wir es also besser? Der beste Weg, um ein Plugin zu reparieren, ist es immer, den Plugin-Autoren auf den Fehler aufmerksam zu machen. Und das ist genau, was ich getan habe. Ich konnte das Plugin bei Github finden, habe den Fehler in einem Fork behoben und für den Autoren einen Pull Request eröffnet. Da es aber einige PRs gab, die schon lange existierten und noch nicht gemerged waren und da es seit über 2 Jahren kein Update gab, habe ich nicht damit gerechnet, dass meine Fehlerlösung schnell veröffentlicht wird. Also war es jetzt OK, dass ich das Plugin erst einmal selbst reparierte? Das hätte ich natürlich tun können, aber es gab noch einen anderen Weg. Ich konnte das Plugin von außen fixen, was eigentlich sehr einfach ist.

Viele Entwickler kennen vermutlich die Funktion load_plugin_textdomain, aber wie viele so benannter Funktionen gibt es in WordPress auch eine Funktion, die das genaue Gegenteil macht. In diesem Fall können wir die Funktion unload_plugin_textdomain nutzen:

function broken_plugin_wpml_fix() {
	unload_textdomain( 'broken-plugin' );
	load_plugin_textdomain( 'broken-plugin', false, 'broken-plugin/languages' );
}
add_action( 'after_setup_theme', 'broken_plugin_wpml_fix', 13 );

Innerhalb einer weiteren Callback-Funktion auf den Hook after_setup_theme enladen wir also zuerst die Sprachdatei und fügen sie anschließend mit dem gleichen Aufruf wie im Plugin neu hinzu. Wir verwenden hierbei eine Priorität, die um eins höher als im Plugin liegt. Somit funktioniert unser Fix auch dann noch, wenn das Plugin schon repariert wurde, wir das aber noch nicht mitbekommen haben.

Diesen Code kopieren wir in ein kleines Plugin (oder vorübergehend in die functions.php Datei des Themes) und sobald das Plugin gefixt wurde, können wir ihn wieder entfernen.

Fazit

Wie ihr an diesem kleinen Beispiel erkennen könnt, ist es oft möglich, ein fehlerhaftes Plugin zu reparieren, ohne den Code selbst verändern zu müssen. Auch bei einem Update funktioniert der Fix dann weiterhin. Ich würde aber immer empfehlen, erst einmal dem Plugin-Autoren einen Fix zu schicken. Einige sind wirklich sehr schnell bei der Veröffentlichung von solchen Patches und ihr erspart euch dann die externe Korrektur. Viel wichtiger noch: ihr löst das Problem dann nicht nur für eure Seite, sondern auch für alle anderen Nutzer, die eventuell das gleiche Problem haben.

Veröffentlicht von

Bernhard ist fest angestellter Webentwickler, entwickelt in seiner Freizeit Plugins, schreibt in seinem Blog über WordPress und andere Themen, treibt sich gerne bei den WP Meetups in Berlin und Potsdam herum und läuft nach Feierabend den ein oder anderen Halbmarathon.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert