Doppelt geladene Sprachdateien verhindern

Die Zeiten ändern sich.

Dieser Beitrag scheint älter als 2 Jahre zu sein – eine lange Zeit im Internet. Der Inhalt ist vielleicht veraltet ...

Häufig führen mich Website-Projekte zu Bugs und bei der Recherche entdecke ich ein Rabbit Hole und finde Spannendes. So auch hier. Das Problem trat in einer tschechischen Website auf, die in meinem Profil auf Deutsch gestellt war. Aus irgendeinem Grund begrüßten mich jedoch ein paar wenige Plugins halb in Deutsch und halb in Tschechisch. Also machte ich mich auf die Suche und entdeckte noch viel mehr …

Als erstes vermute ich natürlich einen Fehler von mir (Hallo Impostor Syndrom! 👋) und fragte mal auf Twitter, ob ich irgendwas übersehen habe:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von Twitter.

Weitere Hinweise und Google-Recherchen brachten mich dann zu einem Github-Issue welches genau mein Problem beschrieb. Der gleiche User (ein Polylang-Entwickler) hat für Twenty Twenty One auch ein Trac-Ticket eröffnet.

Aber worum geht es jetzt genau? Wenn eine der Übersetzungsfunktionen benutzt wird, bevor die Übersetzung korrekt geladen wurde, also z.B. durch eine Funktion wie load_plugin_textdomain oder load_theme_textdomain dann triggert das eine interne Funktion namens _load_textdomain_just_in_time. Je nachdem wie früh diese Funktion getriggert wird, ist womöglich noch nicht die korrekte Locale eingestellt (sofern im Profil etwas anderes als für die Site definiert wurde). Das führt dazu, dass nun im besseren Fall die Sprachdatei zweimal geladen wird, im schlechteren Fall werden zwei unterschiedliche Sprachen geladen. Wie in meinem Fall. Und wenn dann noch dazu kommt, dass die Sprachdatei nicht vollständig sind, dann passiert genau das, was mir aufgefallen ist. Ein Misch-Masch zwischen zwei Sprachen.

Über das großartige Plugin Query Monitor von Jack Blackbourn lässt sich das hervorragend im language-Reiter einsehen:

Hier ist schön zu sehen, dass vor dem korrekten Call via twenty_twenty_one_setup()noch ein weiterer Call durch _load_textdomain_just_in_time stattfindet. Beide laden in diesem Fall die gleiche Sprachdatei. Auch wenn die 16 KB im Speicher sicher nicht sooo schlimm sind. Im Zusammenhang mit mehreren, unterschiedlichen Sprachen, unvollständigen Übersetzungsdatei, vielen problematischen Plugins/Themes oder deutlich größeren Sprachdateien kann das durchaus irgendwann zu einem Problem werden.

Das Gemeine an diesem Problem ist, dass es nicht so einfach zu testen ist. Da es hier um die Reihenfolge der Funktionen geht und der Aufruf der Übersetzungsfunktion selbst keinen Fehler ausgibt, landet nichts im Fehlerlog, es bricht nichts ab oder wird irgendwo ausgegeben. Kein Syntaxcheck schlägt an und kein Coding Standard oder Linter meckert. Eine Suchfunktion, wie das WPDirectory hilft uns auch nicht.

Nur durch ein Tool wie Query Monitor, welches genau ausgibt, was geladen wird, zeigt uns das Ausmaß. Und das ist gewaltig. Antispam Bee, Cachify, Contact Form 7, Cookie Law Info, Ninja Forms, Snitch, WP Google Maps, …

Alle diese Plugins triggern _load_textdomain_just_in_time, aber nicht immer wird auch eine zweite Übersetzungsdatei geladen. Leider gibt es jetzt eben keine einfache Methode, um herauszufinden warum und wo das passiert.

Alex Kirk hatte auf Twitter noch den Tipp sich dazu über einen Filter einen Backtrace ausgeben zu lassen:

add_filter( 'load_textdomain_mofile', 'debug_print_backtrace', 0, 0 );

Aber das ist sehr mühsam. Es geht vor allem darum, zu schauen, wann genau welcher Code ausgeführt (nicht geparst!) wird. Manchmal ist vielleicht der Hook falsch, oder der Code wird gar nicht über einen Action Hook ausgeführt (wie in dem oben erwähnten Trac-Ticket zu Twenty-Twenty-One).

Schaut doch mal mit Query Monitor in eure Installationen und checkt die Plugins/Themes. Bei den Pluginkollektiv-Plugins werde ich Schritt für Schritt schauen, was das auslöst.

Teilt gerne eure Erfahrungen in den Kommentaren!

Schreibe einen Kommentar

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