WP Residence Help WP Residence Help

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

Taxonomy Translation — Developer Guide

62 views 0

This article maps the taxonomy translation subsystem in the wpresidence-translate plugin (text domain wpr-translate). It covers the settings storage, the term duplication pipeline, the hierarchy synchronizer, admin list-table filters, and the adv6 search compatibility shim. For the broader plugin architecture underpinning a multi-language real estate website, see the plugin overview.

Files In Scope

File Role
includes/translation-taxonomies.php Runtime: mode resolution, term duplication, hierarchy sync, term-list filters.
includes/admin/taxonomy-translation.php Admin UI helpers: columns, language filter views, add-translation request handler, edit-term panel.
includes/admin/taxonomy-metabox-filters.php Post-editor metabox filters (get_terms_args, terms_clauses, get_terms, get_the_terms).
includes/admin/views/settings-taxonomy.php Settings screen view (posted to options.php, group wpr_translate_settings).
includes/adv6-terms-compat.php Maps wp_estate_adv6_taxonomy_terms term IDs to the active language.

Settings Storage

Everything lives under the single plugin option wpr_translate_settings:

array(
    'taxonomy_modes'          => array( $taxonomy_slug => 'translate' | 'not_translatable' ),
    'taxonomy_auto_duplicate' => array( $taxonomy_slug => bool ),
    ...
)

Readers:

  • wpr_translation_get_taxonomy_modes_settings()
  • wpr_translation_get_taxonomy_mode( $taxonomy ) – default translate.
  • wpr_translation_is_taxonomy_translatable( $taxonomy ) – main gate used everywhere.
  • wpr_translation_get_taxonomy_auto_duplicate_settings()
  • wpr_translation_is_taxonomy_auto_duplicate_enabled( $taxonomy )

The settings view at includes/admin/views/settings-taxonomy.php renders a row per public taxonomy and preserves hidden values for taxonomies not in the current form (so a temporarily-hidden CPT does not lose its preference).

Element Type & Translation Groups

Each taxonomy maps to a translation element type via wpr_translation_get_taxonomy_element_type( $taxonomy ). Translation groups are stored in {$wpdb->prefix}wpestate_translation_translations with columns including element_id, element_type, trid, language_code, source_language_code, original, and needs_update.

Lookup helpers (defined elsewhere in the plugin but called here):

  • wpr_translation_get_translation_group( $term_id, $element_type ) – returns { trid, translations[code => id], source_language }.
  • wpr_translate_resolve_original_term_id( $term_id, $taxonomy ) – canonical anchor via term meta.
  • wpr_translate_lookup_translated_term_id_strict( $canonical_id, $taxonomy, $language ) – strict mapping with no fallback.
  • wpr_translate_link_term_translation_meta( $source, $target, $language, $taxonomy ) – writes meta linkage (wpr_original_term_id and language code).

Term Duplication Pipeline

wpr_translation_duplicate_term_for_language( $source_term_id, $taxonomy, $target_language, $args ) is the entry point. It:

  1. Validates inputs and rejects non-translatable taxonomies.
  2. Resolves the canonical source via wpr_translate_resolve_original_term_id().
  3. Short-circuits if a translation already exists (meta-first lookup, then translation group).
  4. Resolves the translated parent term id for hierarchical taxonomies.
  5. Generates a unique slug with wp_unique_term_slug().
  6. Sets the global guard $GLOBALS[‘wpr_translation_creating_term_translation’] to suppress recursive created_term handling.
  7. Calls wp_insert_term(). On term_exists error it reuses the existing ID.
  8. Copies term meta via wpr_translation_duplicate_term_meta() and the legacy taxonomy_{term_id} option (resetting category_tagline).
  9. Links meta and writes a row to the translation table via wpr_translation_insert_translation_record().

Created / Edited / Deleted Term Hooks

Action Callback What it does
created_term (pri 20) wpr_translation_handle_created_term Generates a new trid, inserts the source record, and fans out duplication to all other languages when auto-duplicate is enabled.
edited_term (pri 20) wpr_translation_handle_edited_term Reads wpr_translation_term_language and wpr_translation_term_source from POST (with nonce wpr_translation_term_language_{term_id}), updates the group, and syncs hierarchy.
delete_term (pri 20) wpr_translation_handle_deleted_term Removes the translation row; if the deleted term was the original, promotes another translation to original via translation_id update.

Hierarchy Sync

wpr_translation_sync_term_translation_hierarchy( $term_id, $taxonomy ) loads the parent’s translation group, finds the per-language translated parent ID, and calls wp_update_term() on each sibling with the correct parent. The recursion guard $GLOBALS[‘wpr_translation_syncing_term_parents’] prevents re-entry through edited_term while the sync is running.

Front-End Term Filtering

wpr_translation_filter_terms_for_hidden_modes() hooks get_terms at priority 20. It:

  • Skips admin, REST (wpr_translate_language_router_is_rest_request()), and non-translatable taxonomies.
  • Resolves the current language via wpr_translate_get_current_language(), falls back to wpestate_get_current_language().
  • For each term: resolves canonical id, then looks up the language-specific id (wpr_translate_lookup_translated_term_id_strict). For the default language, canonical is always used.
  • For modes where untranslated terms should not be hidden (wpr_translation_should_hide_untranslated_terms()), falls back to canonical so output does not disappear.
  • Rebuilds the result respecting $args[‘fields’] – supports all, ids, tt_ids, names, id=>parent, id=>name, id=>slug.
  • Deduplicates by taxonomy|parent|lowercase(name) to avoid duplicate labels.

wpr_translation_force_terms_filters_args() hooks get_terms_args and forces suppress_filters = false when any queried taxonomy is translatable, so the filter above can actually run.

Admin List Table & Edit Screen

Registered in wpr_translation_bootstrap_taxonomy_admin():

add_action( 'admin_init',      'wpr_translation_setup_taxonomy_columns' );
add_action( 'admin_init',      'wpr_translation_handle_add_term_translation_request' );
add_action( 'current_screen',  'wpr_translation_register_taxonomy_language_filter_hooks' );
add_action( 'edit_term_form',  'wpr_translation_render_term_language_panel', 10, 2 );

The language filter injects per-language views into views_{screen_id} with a wpr_term_language query var. The add-translation handler nonces requests using wpr_translation_get_term_translation_nonce_action( $term_id, $taxonomy, $language ).

Post Editor Metabox Filters

includes/admin/taxonomy-metabox-filters.php registers filters on current_screen and uses the four-filter pattern documented at the top of the file:

get_terms_args   -> high-level arg adjustments
terms_clauses    -> SQL JOIN/WHERE for language
get_terms        -> post-query list filtering
get_the_terms    -> per-post term list filtering

Advanced Search (adv6) Compatibility

wpr_translate_filter_adv6_terms_in_theme_options() in adv6-terms-compat.php hooks the WPResidence theme options and rewrites wp_estate_adv6_taxonomy_terms so that term IDs configured by admins for the advanced search tab are mapped to their current-language equivalents. This keeps “For Sale / For Rent” and similar action filters pointing at the right terms in every language, using the same wpr_translate_resolve_original_term_id and wpr_translate_lookup_translated_term_id_strict pair as the main filter.

Screenshot: The WPResidence advanced search tab configuration showing mapped term IDs

Extension Points

  • Add or remove translatable taxonomies by writing directly to wpr_translate_settings[‘taxonomy_modes’] in a migration.
  • Skip a specific taxonomy from auto-duplication by setting its taxonomy_auto_duplicate entry to false.
  • Use suppress_filters = true on get_terms / WP_Term_Query when you explicitly need the raw cross-language term list (e.g. admin exports).
  • Override wpr_translate_lookup_translated_term_id_strict via a plugin if you need a custom resolver – it is called everywhere through function_exists() checks.

Gotchas

  • The delete_term handler promotes a replacement only when the deleted term was the group’s original – non-original deletions simply drop the mapping row.
  • Non-Latin slugs: wp_unique_term_slug() uses sanitize_title(), which transliterates. If you need to preserve the original script, pre-set a slug before calling wp_insert_term().
  • The hierarchy sync only runs for taxonomies marked hierarchical in register_taxonomy().
  • REST requests are intentionally skipped by the term filter – term assignment UIs must see the full cross-language term pool.

Related Reading

  • Translation Linking (trid system) – the shared TRID mechanism used for both posts and terms.
  • WP_Query Language Filtering – the sibling subsystem for posts.
  • Database Schema – structure of the translations table.

Product context: multi-language real estate website.

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