This article maps WPEstate Translate for developers: where the code lives, what runs at boot, what is stored in the database, and where to hook in. The plugin folder is wpestate-translate and the text domain is wpr-translate. For what the plugin does for site owners, see WPEstate Translate Plugin Overview.
Entry Point and Constants
wpestate-translate.php carries the header (Plugin Name: WPEstate Translate, Version: 1.0.9). It defines the constants, loads the include map and registers the activation and uninstall hooks.
| Constant | Value |
|---|---|
WPR_TRANSLATE_PLUGIN_ROOT, alias WPR_TRANSLATE_PATH |
Plugin folder path, with a trailing slash. |
WPR_TRANSLATE_PLUGIN_URL, alias WPR_TRANSLATE_URL |
Plugin folder URL, with a trailing slash. |
WPR_TRANSLATE_BASENAME |
plugin_basename( __FILE__ ) |
WPR_TRANSLATE_VERSION |
Still hard-coded to 0.1.0, not the release number. Read the plugin header when you need the version. |
Include Map and Bootstrap
The entry file loads a fixed list, in this order:
includes/activator.php
includes/theme-wpr-locator.php
includes/translation-directories.php
includes/translation-files.php
includes/translation-runtime.php
includes/date-localization.php
includes/custom-field-rules.php
includes/translation-hooks.php
includes/sibling-map.php
includes/language-manager.php
includes/main-lang-functions.php
includes/language-rewrite-bases.php
includes/language-permalinks.php
includes/language-router.php
includes/functions-language.php
includes/functions-permalinks.php
includes/body-language-attribute.php
includes/meta-sync.php
includes/custom-fields-sync.php
includes/theme-widget-strings.php
includes/admin/theme-widget-strings.php
includes/plugin-bootstrap.php
language-manager.php loads the includes/language-context/ modules. plugin-bootstrap.php comes last and loads everything else on every request, admin and front end: the relationship modules, nav menu modules, admin screens, post list and editor, auto-translate, Elementor, the language switcher widget, query filters, SEO tags and compatibility layers.
Activation and Uninstall
wpr_translate_activate_plugin() (activator.php) runs on every activation:
- Drops the four unused legacy tables (slugs, languages, glossary, memory) and creates the two plugin tables with
dbDelta(). - Adds the
wpr_translate_versionoption. - Seeds the language catalog and, if no language exists yet, adds the site locale as the default language.
- Merges the default settings (
sync_mediaonly) and runs the locale migration. - Loads the Custom Field Rules from the theme JSON.
- Stamps an empty
_wpr_language(the default language) on existing posts that have none. - Calls
flush_rewrite_rules().
wpr_translate_uninstall_plugin() deletes only these options: wpr_translate_version, wpr_translate_languages, wpr_translate_language_catalog, wpr_translate_settings, wpr_translate_locale_migration_237, wpr_translate_locale_migration. The tables, post and term meta, and translated content stay. Full details: Installation, Activation and Uninstall.
Where Data Is Stored
| Data | Storage |
|---|---|
| Translation links between posts | Post meta: _wpr_language on every post, _wpr_translations on the source, wpr_translated_original_post_id and wpr_translated_language on each translation. |
| Translation links between terms | Term meta: wpr_term_language, wpr_translated_term_{lang} on the source, wpr_original_term_id on each translation. |
| Theme and plugin string translations | Table {prefix}wpestate_translation_strings, exported to .mo files by Generate translation files. |
| Links made by older versions | Table {prefix}wpestate_translation_translations (the trid table). It is read as a fallback when an object has no link meta. Nothing writes new rows. |
| Languages, settings, rules | Options, see below. |
Read links through the relationship API (wpr_translate_relationship_get_post_family(), wpr_translate_relationship_resolve_post() and the term versions), not by querying meta or the table directly. See Translation Linking and Database Schema Reference.
Options
| Option | Content |
|---|---|
wpr_translate_languages |
Configured languages (code, locale, name, slug, flag, is_default, is_active, is_public, formats). The default language is the entry with is_default. |
wpr_translate_language_catalog |
The predefined language catalog. |
wpr_translate_settings |
url_strategy (always subdirectory), sync_media, elementor_compatibility, taxonomy_modes, taxonomy_auto_duplicate, menu_language_switcher. There is no default language key: the sanitizer removes default_language. |
wpr_translate_auto_translation |
Translation provider settings and API keys. |
wpr_cf_rules_defaults, wpr_cf_rule_overrides, wpr_cf_file_state |
Custom Field Rules: defaults from the theme JSON, overrides from the admin screen. |
wpr_translate_version |
Written on activation. |
wpr_translate_admin_register_settings() in includes/admin/menu.php registers wpr_translate_languages, wpr_translate_settings and wpr_translate_auto_translation.
Admin Menu
wpr_translate_admin_register_menus() adds the top-level WPEstate Translate menu (slug wpr-translate-overview, capability manage_options) with these submenus:
| Slug | Label |
|---|---|
wpr-translate-overview |
Start Here |
wpr-translate-languages |
Languages |
wpr-translate-strings |
Theme & Plugins Strings |
wpr-translate-taxonomies |
Taxonomy Translation |
wpr-translate-custom-fields |
Custom Field Rules |
wpr-translate-automatic-translation |
Automatic Translation |
wpr-translate-menu-sync |
Menu Synchronization |
wpr-translate-settings |
Settings |
The views are in includes/admin/views/.
Subsystems
| Subsystem | Primary files |
|---|---|
| Languages and catalog | language-manager*.php, language-context/*.php, language-catalog.php, main-lang-functions.php, functions-language.php |
| URL routing and permalinks | language-router.php, language-permalinks.php, language-rewrite-bases.php, permalinks-helpers.php, functions-permalinks.php, body-language-attribute.php |
| Translation links | translation-relationships*.php, sibling-map.php |
| Query language filter | query-filter.php, query-filter-helpers.php, translation-taxonomies.php |
| Meta and custom field sync | meta-sync.php, custom-fields-sync.php, custom-field-rules*.php |
| SEO and hreflang | seo-tags.php, seo-tags-helpers.php |
| Elementor and shortcodes | elementor-widget-compat.php, shortcode-compat.php, adv6-terms-compat.php, admin/elementor-*.php |
| Nav menus | nav-menu-*.php, admin/nav-menus*.php |
| Post list and editor | admin/post-list-*.php, admin/post-editor.php, admin/editor-header-language.php |
| String translation | translation-runtime.php, translation-files.php, string-catalog*.php, admin/string-*.php |
| Automatic translation | admin/auto-translate-*.php, admin/translation-request.php |
| Maintenance | admin/cache-purge.php, admin/delete-translations.php, admin/reset-settings.php |
Extension Points
| Hook | Where | Use |
|---|---|---|
wpr_current_language |
functions-language.php | Filter that returns the current language code. |
wpr_object_id |
functions-language.php | Filter that returns the translated ID of an object. |
wpr_translate_language_router_skip_detection, wpr_translate_language_router_skip_prepare, wpr_translate_language_router_force_prepare |
language-router.php | Control language detection and request preparation for special routes. |
wpr_translate_should_sync_post_meta, wpr_translate_meta_field_behaviors |
meta-sync.php | Skip meta sync or change field behaviors. |
wpr_translate_custom_field_rules_file, wpr_translation_custom_field_rule, wpr_translation_custom_field_preferences |
custom-field-rules.php, admin/post-list-meta.php | Change the rules file or single rules. |
wpr_translate_runtime_translation |
translation-runtime.php | Change a string translation at runtime. |
wpr_translate_custom_translations_directory, wpr_translate_custom_translations_directory_candidates |
translation-directories.php | Change where translation files are loaded from. |
wpr_translate_auto_translation_excluded_post_types |
admin/settings-helpers.php | Exclude post types from automatic translation. |
wpr_translate_strings_per_page |
admin/string-query.php | Rows per page on the strings screen. |
1.0.9 fires no action when a translation is linked. The old wpr_translation_created action sits in a legacy writer that nothing calls. To react to new links, watch added_post_meta and updated_post_meta for _wpr_translations.
Gotchas
- The language comes from the URL prefix only. There is no cookie or browser-language detection. See Language Detection and Redirects.
- The default language is the
is_defaultflag inwpr_translate_languages, set on the Languages screen. - Uninstall keeps both tables. Reset Translation Settings truncates both tables, deletes the plugin options (including API keys and Custom Field Rules overrides) and runs activation again. Translated posts and terms stay.
- Activation merges settings with
wp_parse_args(), so existing values survive reactivation. - Queries with
suppress_filtersare not language-filtered. See WP_Query Language Filtering.