WP Residence Help WP Residence Help

  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API
Home / WPEstate / WPResidence Translate Plugin / Elementor Widget Translation — Developer Guide

Elementor Widget Translation — Developer Guide

106 views 0

This article is the developer companion to the user-facing article on Elementor translation. It documents the code paths that let WPResidence Translate read Elementor layouts, build a translation payload, and write translated values back into _elementor_data. Product context lives on the multi-language real estate website page.

File Map

File Role
includes/elementor-widget-compat.php Front-end integration: re-renders Elementor shortcode widgets and primes Search Form Builder term data.
includes/admin/elementor-translate-builder.php Builds translation payloads from stored Elementor data. Loads the widget field map and decodes _elementor_data.
includes/admin/elementor-translate-text.php Walks Elementor layouts and extracts translatable text nodes.
includes/admin/elementor-translate-apply.php Resolves taxonomy/post IDs and writes translated payloads back into the translated post’s Elementor data.

Bootstrap

Front-end hooks are registered by wpr_translate_bootstrap_elementor_widget_compat(). It is idempotent via a static flag and attaches three hooks:

add_filter( 'elementor/widget/render_content', 'wpr_translate_filter_elementor_shortcode_widget_content', 10, 2 );
add_action( 'elementor/frontend/widget/before_render', 'wpr_translate_prepare_search_form_builder_frontend_ids', 20, 1 );
add_action( 'elementor/frontend/widget/before_render', 'wpr_translate_log_agent_grids_frontend_ids', 20, 1 );

The compat layer is gated by wpr_translate_is_elementor_compat_enabled(), which reads the elementor_compatibility key from the wpr_translate_settings option and defaults to enabled.

Detecting Elementor Pages

Only pages with Elementor builder data enter the translation pipeline. wpr_translate_is_elementor_page( $post_id, $post_type ) checks two meta keys:

_elementor_data       // the serialized JSON layout blob
_elementor_edit_mode  // Elementor's edit mode flag

If either is non-empty on a page post type, the page is considered an Elementor page.

Widget Field Map

wpr_translate_load_translatable_elementor_widget_fields() merges three JSON sources, in order of increasing priority:

  1. Bundled defaults at WPR_TRANSLATE_PATH . ‘assets/config/translatable_default_elementor_widgets.json’.
  2. Parent theme override at get_template_directory() . ‘/wpr/translatable_widget_fields.json’.
  3. Child theme override at get_stylesheet_directory() . ‘/wpr/translatable_widget_fields.json’.

Each widget key maps to a list of fields. Fields can be plain text (translated as strings), taxonomy references (term IDs or slugs), or post ID references.

 

Text Extraction

wpr_translate_extract_elementor_text_fields( $raw_elementor_data ) walks the decoded layout recursively and collects string values from known widget settings keys (title, heading, text, button_text, label). Each value is stripped of HTML via wp_strip_all_tags() and returned as an ordered, filtered list of unique text nodes for the translation editor / auto-translate providers.

Taxonomy Alias Resolution

WPResidence Elementor widgets store taxonomy references under field aliases like action_ids, category_data, county_data. Real taxonomy slugs are required to look up translated terms. wpr_translate_resolve_elementor_taxonomy_slug( $field_name, $field_value, $allow_alias_without_numeric ) maps the alias to the registered taxonomy, using an explicit alias map:

action_ids   => property_action_category
area_ids     => property_area
category_ids => property_category
city_ids     => property_city
county_data  => property_county_state
features_ids => property_features
status_ids   => property_status

The mapping only runs when the field value contains numeric term IDs, unless $allow_alias_without_numeric is true.

ID Normalizers

Function Purpose
wpr_translate_normalize_elementor_ids() Accepts string, JSON-encoded list, or array. Returns an array of absint IDs.
wpr_translate_normalize_elementor_slugs() Returns a de-duplicated list of sanitized slugs.

Apply Pipeline

wpr_translate_apply_elementor_widget_translations( &$elements, $config, $elementor_translate, $language, &$term_report ) is the workhorse. It traverses the Elementor element tree in place and for each widget listed in the field map it:

  • Overwrites text fields with entries from $elementor_translate.
  • Resolves taxonomy payloads via wpr_translate_resolve_elementor_taxonomy_ids() or wpr_translate_resolve_elementor_taxonomy_slugs().
  • Shapes the result to match the original field via wpr_translate_match_elementor_setting_shape().
  • Appends audit rows to $term_report via wpr_translate_collect_elementor_term_report_entry().

wpr_translate_apply_elementor_translations( $post_id, $translated_payload, $target_language ) is the public entry point that persists the updated payload back to _elementor_data.

Taxonomy Term Resolution

wpr_translate_resolve_elementor_taxonomy_ids( $taxonomy_entry, $language ) tries, in order:

  1. Strict term-ID lookup via wpr_translate_lookup_translated_term_id_strict().
  2. Fallback term-ID lookup via wpr_translate_lookup_translated_term_id().
  3. Slug lookup via wpr_translate_lookup_translated_term_id_by_slug().
  4. Name lookup as a last resort.

Every candidate must pass term_exists() in the target taxonomy before being accepted.

Front-end Search Form Builder Priming

wpr_translate_prepare_search_form_builder_frontend_ids() runs on elementor/frontend/widget/before_render for widgets whose get_name() is WpResidence_Search_Form_Builder. It:

  1. Reads the tabs_field setting and the matching taxonomy data setting (action_data, category_data, etc.).
  2. Normalizes term IDs, loads WP_Term instances, and builds a term_id => name map.
  3. Writes the map to a transient keyed by ‘wpestate_elementor_tax_’. When wpestate_set_transient_name_multilang() exists, the transient key is language-scoped to avoid cross-language cache collisions.
  4. The transient TTL is six hours.

Elementor Shortcode Widget

wpr_translate_filter_elementor_shortcode_widget_content() handles Elementor’s generic shortcode widget. If Elementor returned the shortcode string verbatim (i.e., the shortcode was not executed, typical in live previews), the filter calls do_shortcode() so the plugin’s pre_do_shortcode_tag translation hook in shortcode-compat.php can run.

 

Extension Points

  • Add a widget – drop an entry keyed by the Elementor widget name into wpr/translatable_widget_fields.json in your child theme.
  • Override a resolver – copy wpr_translate_resolve_elementor_taxonomy_slug() behaviour by extending the alias map in a custom filter wrapping this function, guarded by function_exists().
  • Disable compat – set elementor_compatibility to false in the wpr_translate_settings option.

Gotchas

  • Elementor stores layouts as JSON inside a post meta; maybe_unserialize() plus json_decode() is needed. Always round-trip through both functions when writing back.
  • The apply function mutates $elements by reference. Clone the array first if you need the original.
  • Non-Latin text fields must not be pushed through sanitize_title(). Use sanitize_text_field() or a custom escaper.
  • Search Form Builder uses the front-end transient strictly as a display cache. It is not authoritative – the real term resolution happens through the translation tables.

Further Reading

  • Shortcode & Widget ID Remapping – the shortcode-level ID swap used by the Elementor shortcode widget.
  • Taxonomy Translation – the lookup helpers referenced here.
  • Translation Linking (trid system) – how translated post IDs are resolved.

For the broader feature set, see our multi-language real estate website page.

WPEstate / WPResidence Translate Plugin

Related Articles

  • String Scanner — Developer Guide
  • The String Scanner
  • Gettext Pipeline & MO Files — Developer Guide
  • Gettext & MO Files — Making Translations Appear on the Front End

Help Categories

  • 18Agent, Agency & Developers
  • 5Blog Posts & Blog Lists
  • 38Elementor Shortcodes Built-In
  • 45FAQ
  • 15Footer
  • 5Getting Started
  • 37Header
  • 2IDX & MLSImport
  • 6Installation & Setup
  • 23Installation FAQ
  • 23Maps & Location Settings
  • 21Multi-Language - Third Party Plugins
  • 6Other Third party Plugins
  • 20Pages
  • 4Payments & Monetization
  • 20Property Lists, Categories & Archive
  • 37Property Pages & Layouts
  • 31Search & Filtering
  • 162Technical how to | Custom Code Required
  • 8Technical: Actions and filters
  • 6Technical: Child Theme
  • 86Theme Options & Global Settings
  • 7Translations & Languages
  • 16WPBakery Shortcodes
  • 50WPEstate / WPResidence Translate Plugin
  • 51WPResidence / WPEstate CRM
  • 50WPResidence 5.0 Documentation
  • 8WPResidence Elementor Studio

Join Us On

Powered by WP Estate - All Rights Reserved
  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API