WP Residence Help WP Residence Help

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

Automatic Translation — Developer Guide

80 views 0

This article documents the provider-layer of the wpresidence-translate plugin: the admin view, the settings option, the four provider files, the OpenAI request shape, glossary/memory storage, and the AJAX endpoints that drive bulk runs. It complements the user article and the broader multi-language real estate website overview.

Files Involved

File Role
includes/admin/views/automatic-translation.php Settings form + bulk-run UI (post-type selection, target language, start/stop).
includes/admin/views/glossary-memory.php Glossary editor (source term, preferred translation, context).
includes/admin/auto-translate-openai.php Implemented provider. Entry point wpr_translate_auto_translate_post_openai() and wpr_translate_openai_translate_json_payload().
includes/admin/auto-translate-google.php Stub. Returns WP_Error( ‘wpr_translate_google_not_implemented’ ).
includes/admin/auto-translate-deepl.php Stub. Returns WP_Error( ‘wpr_translate_deepl_not_implemented’ ).
includes/admin/auto-translate-microsoft-azure.php Stub. Returns WP_Error( ‘wpr_translate_azure_not_implemented’ ).

Options & Storage

Option / Table Purpose
wpr_translate_auto_translation Core settings. Keys: enabled, engine, openai_api_key, openai_system_prompt, openai_user_prompt, target_language.
wpr_translate_post_types Per-post-type choice (yes/no) controlling bulk runs.
wpr_translate_glossary Array of glossary entries: source, translation, context.
{prefix}wpestate_translation_glossary Optional database-backed glossary used by the auto-translate layer.
{prefix}wpestate_translation_memory Translation memory keyed by similarity_hash for reuse across jobs.

Settings Form Defaults

The view applies these defaults via wp_parse_args():

'enabled'              => false,
'engine'               => 'openai',
'openai_api_key'       => '',
'openai_system_prompt' => 'You are a translator that converts WordPress post data into the requested language.',
'openai_user_prompt'   => 'Translate the following WordPress post payload into the %1$s language.',

The $engines whitelist currently contains only ‘openai’ => ‘OpenAI’. To expose a second provider as a selectable engine, extend this map in the view and wire up its provider file.

Provider Dispatch

Every provider function accepts the same signature, making dispatch trivial:

wpr_translate_auto_translate_post_openai( $post_id, $language, $payload = array(), $payload_json = '' );
wpr_translate_auto_translate_post_google( $post_id, $language, $payload = array(), $payload_json = '' );
wpr_translate_auto_translate_post_deepl(  $post_id, $language, $payload = array(), $payload_json = '' );
wpr_translate_auto_translate_post_microsoft_azure( $post_id, $language, $payload = array(), $payload_json = '' );

Each returns true|WP_Error. Only the OpenAI implementation does real work today; the others are scaffolded and should be treated as placeholders.

OpenAI Request Shape

wpr_translate_openai_translate_json_payload( $language, $payload_json, $settings_context = ‘default’ ) builds:

  • Endpoint: https://api.openai.com/v1/chat/completions
  • Auth: Authorization: Bearer <openai_api_key>
  • Body:
    {
      "model": "gpt-4o-mini",
      "response_format": { "type": "json_object" },
      "messages": [
        { "role": "system", "content": "<system_prompt> Keep the JSON structure identical. Respond with valid JSON only." },
        { "role": "user",   "content": "<user_prompt_template> Preserve the JSON structure and keys. Respond with JSON only.\n\n<payload_json>" }
      ]
    }
  • Timeout: 540 seconds.
  • Retry: up to 3 attempts on WP_Error or non-2xx responses.
  • User-Agent: WPR-Translate/<WPR_TRANSLATE_VERSION>; <home_url>

A non-OpenAI-key configuration returns WP_Error( ‘wpr_translate_missing_openai_key’ ). Malformed JSON bodies return wpr_translate_openai_invalid_json. Non-2xx responses surface body text via wpr_translate_openai_http_error.

Post Payload Preparation

wpr_translate_auto_translate_post_openai() builds a focused payload so only translatable fields are sent to the model:

array(
  'post_id'          => <int>,
  'language'         => <code>,
  'post_type'        => <sanitised key>,
  'post'             => array( 'post_title', 'post_excerpt', 'post_content' ),
  'post_meta_fields' => array( ... translatable meta ... ),
  'taxonomy'         => array( ... terms prepared for LLM ... ),
  'elementor_translate' => array( ... widget translation hints ... ),
  'original_post_id' => <int>,
);

Taxonomy terms are pre-processed via wpr_translate_prepare_taxonomy_payload_for_llm(). Elementor widget content (where present) is preserved in elementor_translate so widget-level text can be applied back after translation. Encoding uses JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES to keep non-Latin characters intact.

 

AJAX Endpoints

Action Callback Purpose
wp_ajax_wpr_translate_auto_translate_strings wpr_translate_admin_ajax_auto_translate_strings Auto-translate untranslated rows on the String Translation page.
wp_ajax_wpr_translate_get_posts_for_auto_translation wpr_translate_admin_ajax_get_posts_for_auto_translation List posts awaiting bulk translation for the selected language + post types.
wp_ajax_wpr_translate_save_post_type_preferences wpr_translate_admin_ajax_save_post_type_preferences Persist the wpr_translate_post_types option from the UI radios.
wp_ajax_wpr_translate_auto_translate_post wpr_translate_handle_auto_translate_post_ajax Translate one post on demand from the editor header.
wp_ajax_wpr_translate_auto_translate_post_publish wpr_translate_handle_auto_translate_post_publish_ajax Auto-translate on publish.

Glossary & Translation Memory

The glossary UI (views/glossary-memory.php) writes to the wpr_translate_glossary option as a list of { source, translation, context } entries. The option is registered through settings_fields( ‘wpr_translate_glossary’ ). The dedicated database tables {prefix}wpestate_translation_glossary and {prefix}wpestate_translation_memory (created at plugin activation) store larger glossary entries and memory hits indexed by similarity_hash.

Debug Logging

wpr_translate_openai_error_log() emits structured log entries for key lifecycle events:

  • send_payload – payload JSON sent to the LLM.
  • receive_payload_raw – raw response from the LLM.
  • receive_payload_error – HTTP or decoding failure with error code and message.

Use these logs when a translation comes back malformed or a taxonomy mapping ends up under the wrong language code.

Extending With a New Provider

  1. Copy auto-translate-openai.php as auto-translate-myprovider.php.
  2. Replace the HTTP call with your provider’s endpoint and authentication scheme.
  3. Return the same shape (array|WP_Error) so the caller doesn’t need to change.
  4. Extend the $engines map in views/automatic-translation.php to expose the new engine.
  5. Add API-key / endpoint fields to the same view and include them in the sanitiser callback used with register_setting( ‘wpr_translate_auto_translation’, … ).
  6. Wire dispatch: where the plugin currently branches on $settings[‘engine’], add a case ‘myprovider’ mapping to your new function.

UTF-8 Safety

All payloads are JSON-encoded with JSON_UNESCAPED_UNICODE, and the response content is decoded without any sanitisation that would corrupt non-Latin text. Keep this invariant in custom providers – do not run translation output through sanitize_title() or sanitize_key().

 

Known Limitations

  • Google/DeepL/Azure files are stubs – do not advertise them as working integrations.
  • The model is hardcoded to gpt-4o-mini. If you need a different model, fork wpr_translate_openai_translate_json_payload() in a child-theme copy and filter the provider dispatch.
  • OpenAI HTTP timeout is 540 seconds. Match your PHP max_execution_time accordingly for very large posts.

Further Reading

  • Gettext Pipeline & MO Files – how translated strings reach the front end.
  • Custom Field Rules – which meta keys reach the translation payload.
  • Translation Linking (trid system) – how source and translated posts are paired.

For product positioning see the multi-language real estate website page.

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
  • 19Pages
  • 4Payments & Monetization
  • 20Property Lists, Categories & Archive
  • 36Property Pages & Layouts
  • 31Search & Filtering
  • 162Technical how to | Custom Code Required
  • 8Technical: Actions and filters
  • 6Technical: Child Theme
  • 86Theme Options & Global Settings
  • 6Translations & Languages
  • 16WPBakery Shortcodes
  • 51WPResidence / WPEstate CRM
  • 50WPResidence 5.0 Documentation
  • 8WPResidence Elementor Studio
  • 50WPResidence Translate Plugin

Join Us On

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