This article documents the language CRUD layer of the wpresidence-translate plugin (text domain wpr-translate). It covers where language records live, how they are normalized, which helpers resolve the current language, and the admin view that writes to them. The sibling user-facing article shows the screen itself; this page is the code map behind it. For the product angle see the multi-language real estate website guide.
Source Files
| File | Role |
|---|---|
| includes/language-manager.php | Public API – get, resolve, and set the current language. |
| includes/language-manager-helpers.php | Normalization, browser matching, active-languages filter. |
| includes/language-catalog.php | Hardcoded ISO catalog returned by wpr_translate_language_catalog_by_code(). |
| includes/main-lang-functions.php | Entry points used across the plugin and by the theme bridge WP_Estate_Translation. |
| includes/functions-language.php | Legacy compatibility wrappers. |
| includes/admin/views/languages.php | Settings API form – posts to options.php with setting group wpr_translate_languages. |
| includes/admin/views/languages-helpers.php | Prepares the view payload (sorts, merges catalog, computes next_index). |
Storage
All runtime data lives in two WordPress options plus the catalog option seeded at activation.
| Option | Shape |
|---|---|
| wpr_translate_languages | Numerically indexed array of language payloads. Written by the Languages form via Settings API (register_setting() with sanitizer wpr_translate_admin_sanitize_languages). |
| wpr_translate_language_catalog | Full ISO catalog snapshot, written once by the activator so lookups do not depend on the PHP file. |
| wpr_translate_settings | Global settings. Key default_language is mirrored from the per-row is_default flag. |
Language Payload Shape
Every language record is normalized through wpr_translate_normalize_language() before being returned. Callers can rely on these keys being present:
array(
'code' => 'en',
'name' => 'English ( United Kingdom )',
'locale' => 'en_GB',
'slug' => 'en',
'flag' => 'gb',
'display_order' => 0,
'is_default' => '1',
'is_active' => true,
'is_public' => true,
'date_format' => 'F j, Y',
'time_format' => 'g:i a',
)
Public API
| Function | Purpose |
|---|---|
| wpr_translate_get_languages() | All stored languages, normalized. No active/public filter. |
| wpr_translate_get_active_languages( $public_only = true ) | Filtered list: is_active required; is_public required when $public_only is true. |
| wpr_translate_get_default_language() | Row with is_default set, or the first row as fallback. |
| wpr_translate_get_language( $identifier ) | Lookup by slug, code, or locale. Case-insensitive, underscore/hyphen tolerant. |
| wpr_translate_resolve_preferred_language() | Cookie > Accept-Language > default language, gated by the active list. |
| wpr_translate_get_post_language( $post_id ) | Language assigned to a post via the trid tables. |
| wpr_translate_get_context_language( $post_id = 0 ) | Post language when available, otherwise visitor preference, otherwise default. |
| wpr_translate_set_current_language( $language, $options ) | Stores the active language in $GLOBALS[‘wpr_translate_current_language’] and on WP_Estate_Translation::$current_language. Optionally reloads text domains for the locale. |
| wpr_translate_get_language_slug( $language ) | URL slug, empty string for the default language. |
| wpr_translate_is_default_language( $language ) | Comparison on flag, code, locale, slug – in that order. |
Preferred Language Resolution
wpr_translate_resolve_preferred_language() reads in this order:
- $_COOKIE[‘wpestate_translation_lang_pref’] – the cookie written by the frontend switcher via the wpr_translate_set_language_cookie AJAX action.
- The visitor’s Accept-Language header, matched via wpr_translate_match_browser_language().
- wpr_translate_get_default_language().
All comparisons lowercase the locale and replace underscores with hyphens so en_GB, en-gb, and EN-GB all match.
The Languages Admin Form
The view at includes/admin/views/languages.php posts to options.php with setting group wpr_translate_languages. Form fields follow this pattern:
wpr_translate_languages[0][code] wpr_translate_languages[0][name] wpr_translate_languages[0][locale] wpr_translate_languages[0][slug] wpr_translate_languages[0][flag] wpr_translate_languages[0][is_default] wpr_translate_languages[0][is_active] wpr_translate_languages[0][is_public] wpr_translate_languages[0][display_order] wpr_translate_languages[0][date_format] wpr_translate_languages[0][time_format]
A hidden input with value 0 precedes each checkbox so unchecked boxes still submit a value. The radio for default is a UI-only control – the sanitizer promotes it to the per-row is_default string.
The drag-and-drop handle writes back into display_order via the admin script bundle wpr-translate-admin.
Catalog
wpr_translate_language_catalog_by_code() in language-catalog.php returns the full hardcoded catalog – over 200 ISO-keyed entries, each with code, locale, name, slug, and flag. On activation the array is copied to wpr_translate_language_catalog so admin screens can read it without parsing the PHP file.
Theme Bridge
For backwards compatibility with the WPResidence theme’s own translation helpers, wpr_translate_set_current_language() mirrors the active slug onto the static property WP_Estate_Translation::$current_language. Any theme code that checks that property keeps working without being rewritten.
Extending Safely
- Always funnel lookups through the helpers – do not read wpr_translate_languages directly. The helpers normalize legacy payloads and guard against non-array values.
- Do not pass language names through sanitize_title(). Names may be Cyrillic, Arabic, or Chinese; only the slug is ASCII.
- When adding a language programmatically, merge it into get_option(‘wpr_translate_languages’, array()), run each row through wpr_translate_normalize_language(), then call update_option(). Flush rewrite rules afterwards.
- Test against wpr_translate_get_active_languages(false) (includes non-public) before gating UI on count() > 1.
Related Articles
- Settings Page – the global settings option shape.
- URL Structure & Permalinks – how slugs become URL prefixes.
- Translation Linking (trid system) – how language codes map to posts and terms.
See the multi-language real estate website page for product context.