This is the schema reference for the data WPEstate Translate 1.0.9 stores. The plugin creates two custom tables and keeps translation links in post meta and term meta. For a plain-language version, see Where Your Translations Live.
What Is Stored Where
| Data | Storage |
|---|---|
| Language of a post and its translation family | Post meta: _wpr_language, _wpr_translations, wpr_translated_original_post_id, wpr_translated_language |
| Language of a term and its translation family | Term meta: wpr_term_language, wpr_original_term_id, wpr_translated_term_{code} |
| Theme and plugin string translations | {prefix}wpestate_translation_strings |
| Relationships created by older versions | {prefix}wpestate_translation_translations (read as a legacy fallback) |
| Languages, settings, catalog | Options: wpr_translate_languages (the is_default flag marks the default language), wpr_translate_settings, wpr_translate_language_catalog |
Both tables are defined in includes/activator.php inside wpr_translate_activator_create_tables() and installed via dbDelta() on activation. They use the active $wpdb->prefix and $wpdb->get_charset_collate().
Removed Tables
Older versions also created wpestate_translation_slugs, wpestate_translation_languages, wpestate_translation_glossary and wpestate_translation_memory. Nothing read or wrote them. wpr_translate_activator_create_tables() now runs DROP TABLE IF EXISTS on all four, so they disappear the next time the activator runs (activation, or the Reset tool).
Relationship Meta
Posts
| Meta key | On | Value |
|---|---|---|
| _wpr_language | Every post | Language code. Blank means the default language. Activation stamps a blank value on existing posts that have none. |
| _wpr_translations | Source post | Map of language code to post ID for the whole family. |
| wpr_translated_original_post_id | Translation | Source post ID. |
| wpr_translated_language | Translation | Language code of the translation. |
Terms
| Meta key | On | Value |
|---|---|---|
| wpr_term_language | Source and translation | Language code. |
| wpr_translated_term_{code} | Source term | Term ID of the translation in {code}. |
| wpr_original_term_id | Translation | Source term ID. |
Families are written atomically by wpr_translate_relationship_write_post_family() and wpr_translate_relationship_write_term_family() in includes/translation-relationships-writes.php. If any meta write fails, the previous values are restored.
Table {prefix}wpestate_translation_translations (Legacy)
The link table used by earlier versions. Rows sharing the same trid are language variants of the same post or term. In 1.0.9 no code path writes new rows. includes/translation-relationships-legacy.php reads it so families created by older versions still resolve, and The Delete Translations tool includes legacy-only members. Reset Translation Settings truncates it, so families that exist only in this table lose their links.
| Column | Type | Null | Default | Notes |
|---|---|---|---|---|
| translation_id | BIGINT(20) UNSIGNED | No | AUTO_INCREMENT | Primary key. |
| element_type | VARCHAR(45) | No | — | post_{post_type} or tax_{taxonomy}, for example post_estate_property, post_page, tax_property_category. |
| element_id | BIGINT(20) UNSIGNED | No | — | Points at wp_posts.ID or wp_terms.term_id depending on element_type. |
| trid | BIGINT(20) UNSIGNED | No | — | Translation group ID. Same value across all language variants. |
| language_code | VARCHAR(7) | No | — | Language of this variant. |
| source_language_code | VARCHAR(7) | Yes | NULL | Source language this variant was derived from. |
| post_status | VARCHAR(20) | No | publish | Post status copy. |
| translator_id | BIGINT(20) UNSIGNED | Yes | NULL | User ID of the translator. |
| original | TINYINT(1) | No | 0 | 1 = this is the source variant in its trid group. |
| needs_update | TINYINT(1) | No | 0 | Legacy. Not set or displayed by 1.0.9: the functions that set it have no callers. |
| last_updated | DATETIME | No | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | Auto-maintained by MySQL. |
Indexes: PRIMARY KEY (translation_id), KEY trid (trid), KEY element (element_id, element_type), KEY language (language_code).
Relationships: element_id is a soft FK to wp_posts.ID when element_type starts with post_, or to wp_terms.term_id when it starts with tax_. No DB-level FK constraint is declared.
Table {prefix}wpestate_translation_strings
Gettext-style string storage for theme and plugin UI strings. One row per (context, name, language_code).
| Column | Type | Null | Default | Notes |
|---|---|---|---|---|
| string_id | BIGINT(20) UNSIGNED | No | AUTO_INCREMENT | Primary key. |
| context | VARCHAR(255) | No | — | Scope, e.g. theme:wpresidence, plugin:<domain>, or the theme admin strings domain. |
| name | VARCHAR(255) | No | — | String key: str_ followed by md5 of the gettext key (msgctxt + “\4” + msgid, or just the msgid), or a dotted theme-option path. |
| msgctxt | VARCHAR(255) | No | ” | Gettext context, so _x() strings export with their context. |
| value | TEXT | No | — | Original source string (msgid). |
| plural | TEXT | Yes | NULL | msgid_plural, stored on the singular row so the pair exports as one plural entry. |
| language_code | VARCHAR(7) | No | — | Target language of the translation. |
| translation | TEXT | Yes | NULL | Translated value. The default-language row mirrors the source value. Generate translation files skips default-language rows. |
| status | TINYINT(3) UNSIGNED | No | 0 | 0 = untranslated, 1 = translated (always 1 on the default-language row). |
| processed | TINYINT(1) UNSIGNED | No | 0 | Export tracking flag for MO compilation. |
| translator_id | BIGINT(20) UNSIGNED | Yes | NULL | User ID of the last translator. |
| updated_at | DATETIME | No | CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | Auto-maintained. |
| md5 | CHAR(32) | Yes | NULL | md5 of value, used to detect a reworded source. |
Indexes: PRIMARY KEY (string_id), UNIQUE KEY uniq_string (context, name, language_code), KEY language (language_code).
For installs that predate them, the processed, msgctxt and plural columns are added lazily by wpr_translate_admin_ensure_processed_column(), wpr_translate_admin_ensure_msgctxt_column() and wpr_translate_admin_ensure_plural_column() in includes/admin/string-database.php on the next scan or export.
Read-Path Notes
- Language filtering — pre_get_posts / the_posts filters in query-filter.php restrict front-end queries by the _wpr_language post meta. A blank value is treated as the default language.
- Family reads — wpr_translate_relationship_get_post_family() and wpr_translate_relationship_get_term_family() read the meta above and fall back to the legacy table. Results are cached for the rest of the request and flushed on any post, term or metadata change.
- String lookups — wpr_translate_get_runtime_translation_map() in translation-runtime.php loads every translation for one domain and language in a single query, keyed by name. The map is cached per request and in the object cache group wpr_translate_runtime_strings.
Uninstall and Reset
wpr_translate_uninstall_plugin() deletes options only, never tables or meta:
delete_option( 'wpr_translate_version' ); delete_option( 'wpr_translate_languages' ); delete_option( 'wpr_translate_language_catalog' ); delete_option( 'wpr_translate_settings' ); delete_option( 'wpr_translate_locale_migration_237' ); delete_option( 'wpr_translate_locale_migration' );
For a full wipe, drop the two wpestate_translation_* tables and remove the relationship meta manually. Reset Translation Settings (includes/admin/reset-settings.php) truncates both tables, deletes the plugin options including API keys, and keeps posts, terms and their meta. the Delete Translations tool (includes/admin/delete-translations.php) removes translated posts or terms for one language.
Related: Translation Linking, WP_Query Language Filtering, Gettext Pipeline and MO Files, Performance and Caching (Developer Reference).