WP Residence Help WP Residence Help

  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API
Home / WPEstate Translate Plugin / Language Switcher Widget — Developer Reference

Language Switcher Widget — Developer Reference

181 views 0

This article documents the frontend language switcher shipped with WPEstate Translate 1.0.9: widget registration, instance storage, the render pipeline, target-URL resolution and the other places that reuse the same renderer. For the product overview see the multi-language real estate website guide.

CONTENT

  • Source Files
  • Registration
  • Option Storage
  • Request Context
  • Render Pipeline
  • Output Shape
  • Target URL Resolution
  • Navigation and Language Persistence
  • Flags
  • Styling from Theme Options
  • Other Callers of the Renderer
  • Extension Tips
  • Related Articles

Source Files

File Role
includes/widgets/class-wpr-translate-language-switcher-widget.php WPR_Translate_Language_Switcher_Widget (extends WP_Widget) – widget type, single Title field, update() sanitizer.
includes/widgets/language-switcher.php Registration, one-time legacy option migration, request-context capture, inline theme-option CSS.
includes/widgets/language-switcher-display.php Frontend render – wpr_translate_language_switcher_widget_display() and wpr_translate_render_language_switcher_dropdown().
includes/nav-menu-locations-frontend.php Injects the same dropdown into nav menus (Settings > Menu Language Dropdown).

Registration

The switcher is a standard WP_Widget with id_base wpr_translate_language_switcher, title WPResidence Language Switcher, classname wpr-language-switcher-widget and show_instance_in_rest => true. plugin-bootstrap.php hooks wpr_translate_register_widgets() on widgets_init, which calls wpr_translate_register_language_switcher_widget() and then register_widget().

Registered IDs keep the pattern wpr_translate_language_switcher-{N}, so sidebar placements from older versions still resolve.

Option Storage

Option key Shape
widget_wpr_translate_language_switcher (standard WP_Widget storage) array( int $number => array( ‘title’ => string ) )
wpr_translate_language_switcher (legacy, pre-WP_Widget) Read once by wpr_translate_language_switcher_migrate_legacy_instances(), copied into the option above by instance number, then deleted.

Titles are sanitized with sanitize_text_field().

Request Context

wpr_translate_language_switcher_capture_request_context() runs on wp (priority 1) and stores the main-query post ID, or term ID and taxonomy, in $GLOBALS['wpr_translate_language_switcher_request_context']. The renderer reads it through wpr_translate_language_switcher_get_request_context(), so secondary loops in the page body (property lists, sliders) cannot change which object the switcher links from.

Render Pipeline

wpr_translate_language_switcher_widget_display( $args, $widget_args ) is the display callback. In order it:

  1. Reads the title from $widget_args['title'] (menu and Elementor callers pass none).
  2. Calls wpr_translate_get_active_languages() and returns when fewer than 2 languages exist.
  3. Loads the captured request context (post, or term + taxonomy).
  4. Resolves the current language via wpr_translate_get_context_language( $current_post_id ); on term archives it uses wpr_translate_get_element_language( $term_id, 'tax_{taxonomy}' ).
  5. Builds $translation_map (language code => target ID). Posts use wpr_translate_get_sibling_map() (postmeta first, trid table fallback) and skip members whose status is not viewable. Terms use wpr_translate_lookup_translated_term_id_strict() from the original term.
  6. Builds a front-page map from page_on_front so translated front pages link to the language root.
  7. Computes the fallback post URL (default-language member via wpr_translation_get_post_language_permalink(), else get_permalink()) and the fallback term URL.
  8. Emits one <li> per language and wraps them with wpr_translate_render_language_switcher_dropdown().
  9. Prints an inline script that updates the button label/flag on click and navigates.

Output Shape

<div id="wpr-language-switcher-{widget_id}" class="dropdown wpr-language-switcher"
     data-current-post-id="…" data-current-language-code="…"
     data-flag-alt-template="%s flag">
  <button class="btn dropdown-toggle wpr-language-switcher-toggle"
          data-bs-toggle="dropdown" aria-expanded="false"
          data-selected-language-code="…">…</button>
  <ul class="dropdown-menu wpr-language-switcher-menu">
    <li role="presentation">
      <button type="button" class="dropdown-item wpr-language-switcher-item"
              data-language-code="fr" data-translation-id="123"
              data-target-url="…" data-router-url="…"
              data-fallback-url="…" data-flag-url="…"
              data-label="Français">…</button>
    </li>
  </ul>
</div>

Labels drop a trailing bracket such as “English (United States)” → “English”. When the switcher is injected into a menu and wpr_translate_is_wprentals_theme_active() is true, the wrapper gets wpr-language-switcher--wprentals, the list gets sub-menu, rows get menu-item classes, the toggle and items get menu-item-link, the toggle also gets Bootstrap 3 data-toggle="dropdown", and a second inline script handles open/close.

Target URL Resolution

For each language the item URL is chosen in this order:

  1. Direct translation – wpr_translation_get_post_language_permalink() for posts; for terms get_term_link() passed through wpr_translate_prefix_url_for_language().
  2. Front-page root – when the current post is the front page or one of its translations, wpr_translate_language_router_get_switch_url( $language ).
  3. Fallback post/term URL – the default-language URL of the current post or term.
  4. Router URL – wpr_translate_language_router_get_switch_url( $language ) for archives, search and 404s.

Terms of a taxonomy set to Not Translatable are shared by all languages, so every language maps to the same term and is listed under its own prefix.

Navigation and Language Persistence

On click the inline script navigates to data-target-url, then data-router-url, then data-fallback-url. Nothing is stored on the visitor’s side: the language of the next page is decided only by its URL prefix. The wpestate_translation_lang_pref cookie, the wpr_translate_set_language_cookie AJAX action and the data-can-set-cookie attribute were removed. If your page cache varies on that cookie, remove it from the vary list.

Flags

Flag URLs are built as WPR_TRANSLATE_URL . 'assets/img/flags/4x3/{code}.svg', using the language’s flag field first and its code as fallback. With no flag the <img> has no src and the wrapper gets wpr-language-switcher-flag--hidden.

Styling from Theme Options

wpr_translate_language_switcher_print_inline_styles() (on wp_head, priority 100) reads wp_estate_lang_switcher_font_size, wp_estate_lang_switcher_dropdown_font_size, wp_estate_lang_switcher_background_color and wp_estate_lang_switcher_font_color from the wpresidence_admin option and prints <style id="wpr-translate-language-switcher-inline"> only when at least one is set.

Other Callers of the Renderer

Caller How it calls the renderer
Menu Language Dropdown (wpr_translate_inject_language_switcher_into_menu() on wp_nav_menu_items) Reads wpr_translate_settings['menu_language_switcher'][ $location ] (before / after); passes widget_id wpr-menu-language-switcher-{location} and wpr_translate_menu_injected => true. Menus rendered without theme_location (Studio / Elementor nav widgets) are matched to a location by menu term ID.
Elementor Language Switcher widget (residence-elementor, Wpresidence_Site_Language_Changer, widgets/header-footer/site-language-changer.php; titled Language Dropdown in older residence-elementor builds) wpestate_render_language_dropdown() passes a unique widget_id wpr-language-switcher-elementor-{suffix} so header and footer copies do not collide.

Extension Tips

  • Do not branch on $_SERVER['HTTP_ACCEPT_LANGUAGE'] or cookies. Language is resolved from the URL prefix only.
  • Multiple instances: the wrapper ID comes from $args['widget_id']; give every custom call a unique one.
  • Styling: target .wpr-language-switcher, .wpr-language-switcher-toggle and .wpr-language-switcher-item. Avoid overriding the inline script.
  • Custom switchers: reuse wpr_translate_get_sibling_map() and wpr_translation_get_post_language_permalink() rather than reading the trid table directly.

Related Articles

  • The Language Switcher – placing the switcher, for site owners.
  • Managing Languages – the language list the widget reads.
  • Language Detection & Redirects – how the URL prefix decides the language.
  • Admin Bar Language Switcher & Editor Header Selector – admin-side companion.

See the multi-language real estate website page for product context.

WPEstate 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
MLSImportWordPress IDX Plugin for MLS ListingsImport MLS listings into your WordPress website, customize your property pages, and keep your inventory updated.Start free 30-day trial →

Help Categories

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

Join Us On

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