Das eigentliche Problem: WPML + Themify Builder ist nicht wartbar
Wir betreiben eine mehrsprachige Website mit WPML und Dutzenden von Seiten in mehreren Sprachen. Zwei Bugs machen dieses Setup in der Praxis nicht wartbar:
- Hook Content Conditions, die für die Originalseite gesetzt wurden, greifen nie auf übersetzten Seiten – jede Condition müsste manuell für jede Übersetzung dupliziert werden
- Builder-Styles synchronisieren sich nicht automatisch auf übersetzte Seiten – Redakteure müssen nach jeder Layout-Änderung jede übersetzte Seite manuell im Builder öffnen, um die Styles zu übernehmen
Beide Probleme haben dieselbe Ursache: Themify Builder nutzt die von WPML bereitgestellten Integrations-APIs nicht vollständig.
Hintergrund: Wie WPML Seiten verwaltet
WPML verknüpft Seiten sprachübergreifend über Übersetzungsbeziehungen, die über eine dedizierte API zugänglich sind:
// Übersetzung einer Seite in einer anderen Sprache ermitteln
$translated_id = apply_filters('wpml_object_id', $post_id, 'page', false, $lang);
// Aktuelle / Standard-Sprache abfragen
$current_lang = apply_filters('wpml_current_language', null);
$default_lang = apply_filters('wpml_default_language', null);
Diese APIs existieren genau dafür, damit Plugins WPML-kompatibel arbeiten können, ohne Logik pro Sprache zu duplizieren.
Bug 1: Hook Content Conditions greifen nicht auf übersetzten Seiten
In themify/class-hook-contents.php baut check_visibility() den Seitenpfad über child_post_name():
// class-hook-contents.php ~Zeile 179
in_array( '/' . self::child_post_name( $query_object ) . '/', $posts )
child_post_name() läuft rekursiv über post_parent und konkateniert die post_name-Werte. Auf einer übersetzten Seite liefert das den englischen Slug, z.B.:
/services/production-and-delivery-of-green-hydrogen/
Die gespeicherte Visibility Condition enthält aber den deutschen Slug (Standardsprache):
/leistungen/produktion-und-lieferung-von-gruenem-wasserstoff/
Der in_array()-Vergleich schlägt immer fehl → Hook Content wird auf übersetzten Seiten nie ausgegeben.
Erwarteter Fix – vor dem Vergleich auf die Originalsprachversion zurückauflösen:
$original_id = apply_filters('wpml_object_id', $query_object->ID, 'page', false, $default_lang);
$original_post = get_post($original_id);
$original_path = '/' . self::child_post_name($original_post) . '/';
in_array($original_path, $posts)
Wir haben das als Workaround über template_redirect mit Priorität 11 gelöst und registrieren die fehlenden add_action()-Aufrufe manuell. Es funktioniert – gehört aber in check_visibility() selbst behoben.
Bug 2: Builder-Styles synchronisieren sich nicht auf übersetzte Seiten
Wenn ein Layout in der Standardsprache (Deutsch) aktualisiert wird, speichert Themify Builder das Ergebnis in den Postmeta:
_themify_builder_settings_json
WPMLs Page-Builder-Integration sollte diesen Wert beim Speichern automatisch auf übersetzte Seiten übertragen. In der Praxis synchronisiert sich die Grid-Struktur korrekt, die Styles jedoch nicht. Die übersetzte Seite übernimmt geänderte Styles erst, nachdem sie manuell im Builder geöffnet wurde.
WPML stellt dafür einen dedizierten Hook bereit:
do_action('wpml_page_builder_string_translated', $package_name, $translated_post_id, $data, $lang);
An irgendeiner Stelle in der Übergabe zwischen Themify Builders Speicher-Routine und WPMLs Sync-Mechanismus fehlt etwas – entweder werden die Style-Daten nicht in die Postmeta der Übersetzung geschrieben, oder der Extraktionsschritt wird beim Sync übersprungen.
Der vorgeschlagene Workaround (jede übersetzte Seite manuell als zusätzliche Hook-Content-Condition eintragen) löst keines der beiden Probleme – er verschiebt den Wartungsaufwand nur auf die Redakteure. Ein systematischer Fix unter Nutzung der vorhandenen WPML-Integrations-APIs wäre der richtige Ansatz.