The actual problem: WPML + Themify Builder is not maintainable
We run a multilingual website with WPML and dozens of pages in multiple languages. Two bugs make this setup unmaintainable in practice:
- Hook Content Conditions set for the original page never apply to translated pages – each condition would have to be manually duplicated for each translation
- Builder styles do not automatically synchronize to translated pages – editors must manually open each translated page in the Builder after every layout change to apply the styles
Both problems have the same cause: Themify Builder does not fully utilize the integration APIs provided by WPML.
Background: How WPML manages pages
WPML links pages across languages via translation relationships, which are accessible through a dedicated API:
// Ü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);
These APIs exist precisely so that plugins can work WPML-compatible without duplicating logic per language.
Bug 1: Hook Content Conditions do not apply to translated pages
In themify/class-hook-contents.php builds check_visibility() the breadcrumb trail via child_post_name():
// class-hook-contents.php ~Zeile 179
in_array( '/' . self::child_post_name( $query_object ) . '/', $posts )
child_post_name() recursively runs over post_parent and concatenates the post_name values. On a translated page, this returns the English slug, e.g.:
/services/production-and-delivery-of-green-hydrogen/
However, the saved Visibility Condition contains the German slug (default language):
/leistungen/produktion-und-lieferung-von-gruenem-wasserstoff/
The in_array() comparison always fails → Hook Content is never output on translated pages.
Expected Fix – resolve to the original language version before comparison:
$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)
We solved this as a workaround via template_redirect with priority 11 and manually register the missing add_action() calls. It works—but it should be fixed in check_visibility() itself.
Bug 2: Builder styles don’t sync to translated pages
When a layout is updated in the default language (German), Themify Builder saves the result in the post meta:
_themify_builder_settings_json
WPML’s page builder integration should automatically transfer this value to translated pages when saving. In practice, the grid structure syncs correctly, but the styles do not. The translated page only picks up changed styles after it has been opened manually in the builder.
WPML provides a dedicated hook for this:
do_action('wpml_page_builder_string_translated', $package_name, $translated_post_id, $data, $lang);
Somewhere in the handoff between Themify Builder’s save routine and WPML’s sync mechanism, something is missing—either the style data isn’t written to the translation’s post meta, or the extraction step is skipped during sync.
The suggested workaround (adding every translated page manually as an additional hook content condition) doesn’t solve either problem—it just shifts the maintenance effort to the editors. A systematic fix using the existing WPML integration APIs would be the right approach.