Ultimate Translation Pro
Multilingual support for WordPress with DeepL/Google auto-translation, subdirectory URLs, and Elementor compatibility.
by Daniel Jay · github.com/costaluztransfers-danieljay/ultimate-translation-pro
★ 0stars
0forks
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/costaluztransfers-danieljay/ultimate-translation-pro/archive/refs/heads/main.zipMultilingual WordPress with DeepL/Google auto-translation, subdirectory URLs, and Elementor compatibility.
Description
Ultimate Translation Pro adds multilingual support to WordPress without duplicating posts.
Translations are stored as post meta on the source page and swapped in-memory based on the
URL prefix (/es/, /fr/, /de/).
- Auto-translate via DeepL or Google Translate.
- Subdirectory URLs:
/page/for default,/es/page/for non-default languages. - Elementor compatibility — translates widget text without overwriting source data.
- Language switcher: shortcode
[utp_switcher], classic widget, or sidebar block. - Per-page translation control via the Translations meta box.
Installation
- Upload the
ultimate-translation-profolder to/wp-content/plugins/. - Activate the plugin.
- Go to Translation in the admin menu and add your DeepL API key.
- Edit any page and use the Translations meta box to auto-translate.
Changelog
2.0.6
- Fixed: Elementor body text didn't translate (only the page title was). The
walker used a hardcoded list of setting keys (
title,heading,text, etc.), which missed any widget that stored its text under a non-listed key — including most Elementor Pro and theme-specific widgets. Replaced with a generic walker that visits every string in the settings tree, skipping only keys/values that match technical patterns (URLs, color hex, dimensions, CSS classes, Font Awesome icon names, image filenames). - Fixed: regex bug in URL detection (
#delimiter conflicted with#in the alternation) that incorrectly let URLs andmailto:links through to DeepL. - Added: top-bar (admin bar) entry "Ultimate Translator" with quick links
to Settings and Flush Rewrite Rules, visible on both admin and front-end
for users with
manage_optionscapability. - Changed: admin menu repositioned to sit directly below Ultimate Ads (uses fractional position 24.9, between WP's default Pages and Comments).
- Changed: Elementor widget renamed from "Ultima Translation" → "Ultimate Translator".
- Hardened:
translate_postnow bypasses our ownget_post_metadatafilter when reading source_elementor_data, eliminating any chance of the walker recursing on already-translated data.
2.0.5
- Fixed: critical layout breakage on translated pages — Elementor icons rendered
full-page-width and header images / form widgets disappeared. Cause: the
get_post_metadatafilter was returning slashed JSON ({\"key\":\"value\"}) to Elementor, which expects clean JSON fromget_post_meta(). Elementor'sjson_decodesilently failed on the slashed input, falling back to skeleton rendering with no CSS sizing. Filter now returns clean JSON. - Added: pre-translation guard skips strings that look like CSS classes, hex colors, dimensions, URLs, or Font Awesome icon names. Prevents DeepL from mangling Elementor internal tokens.
- Changed: API keys are NOT migrated from older versions. After upgrade the user must re-enter the DeepL or Google key in Settings → Translation.
- Changed: Elementor widget renamed to "Ultima Translation" and moved to the "Daniel Jay" widget category (matching Ultimate Ads Pro's category registration so both plugins' widgets share one panel section).
- Changed: plugin author updated to "Daniel Jay".
2.0.4
- Fixed:
/es/page/returned WordPress 404 — rewrite rules set bothpagenameandnamequery vars simultaneously, which made WP_Query fail to resolve either pages or posts. Now setspagenameonly, with aparse_requestfallback that demotes tonamewhen no matching page exists. - Added: native Elementor widget for the language switcher. Drag from the Elementor panel under the "Translation" category. Supports text color, hover color, background, border, typography, flag size, and alignment controls.
- Added: two new switcher layouts — "Flags only" (compact, just the flag emojis) and "Pills" (rounded buttons). Total of 5 layouts: dropdown, list, inline, flags, pills.
- Improved: dropdown switcher visibility — thicker border, subtle background fill, hover/press feedback, more padding.
2.0.3
- Full rename from CLT/clt prefixes to UTP/utp across PHP, JS, CSS, and option keys.
- Fixed: translation never executed because DeepL request used legacy
auth_keybody parameter; now usesAuthorization: DeepL-Auth-Keyheader per current DeepL API spec. - Fixed: HTML inside Elementor widgets was being mangled by DeepL; now uses
tag_handling=htmlandpreserve_formatting=true. - Fixed: 5-second default HTTP timeout was killing translations of long pages; now 45 seconds per call, 120s overall PHP limit on AJAX.
- Fixed:
/es/page/URLs not resolving — language detection ran onwp_loaded(too late) and ignored theutp_langquery var. Detection now runs onparse_request(priority 1) and falls back to URL parsing oninit. - Fixed: nested pages like
/es/parent/child/did not work — rewrite rule was too specific. Updated to^es/(.+?)/?$to match any slug depth. - Fixed: critical data-loss bug — v2.0.2 wrote
_elementor_datadirectly on the source post on every front-end render, permanently overwriting the source language with the translation. Now usesget_post_metadatafilter to swap data in-memory only; source data is never modified. - Fixed: rewrite rules never flushed on activation; new installs had no
/es/routes until someone manually visited Permalinks. Now flushed automatically. - Fixed: language-switcher links inherited current language prefix, so on
/es/page/the EN link became/es/page/not/page/. Now temporarily resets to default language when generating cross-language URLs. - Added: Elementor cache flush after translations are saved (prevents stale CSS).
- Added:
x-defaulthreflang tag. - Added: REST/admin AJAX language detection via
?utp_lang=query arg, so the meta-box "Edit translation" links produce a usable admin URL. - Added: bootstrap file with autoloader covering both
includes/andadmin/. - Added: meta box back-compat — auto-registered on all public post types, not only post and page.
2.0.2
- Fixed admin JS not loading on post edit screens.
2.0.1
- Fixed autoloader to include the
admin/directory.
2.0.0
- Architecture rebuild — replaced duplicate-post translation system with meta-based system. Translations stored on the source post.
1.x
- Initial CLT Translate releases (deprecated; renamed to Ultimate Translation Pro).