WP Manifestindependent plugin directory
manifest / i18n / ultimate-translation-pro

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.zip

Multilingual 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

  1. Upload the ultimate-translation-pro folder to /wp-content/plugins/.
  2. Activate the plugin.
  3. Go to Translation in the admin menu and add your DeepL API key.
  4. 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 and mailto: 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_options capability.
  • 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_post now bypasses our own get_post_metadata filter 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_metadata filter was returning slashed JSON ({\"key\":\"value\"}) to Elementor, which expects clean JSON from get_post_meta(). Elementor's json_decode silently 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 both pagename and name query vars simultaneously, which made WP_Query fail to resolve either pages or posts. Now sets pagename only, with a parse_request fallback that demotes to name when 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_key body parameter; now uses Authorization: DeepL-Auth-Key header per current DeepL API spec.
  • Fixed: HTML inside Elementor widgets was being mangled by DeepL; now uses tag_handling=html and preserve_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 on wp_loaded (too late) and ignored the utp_lang query var. Detection now runs on parse_request (priority 1) and falls back to URL parsing on init.
  • 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_data directly on the source post on every front-end render, permanently overwriting the source language with the translation. Now uses get_post_metadata filter 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-default hreflang 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/ and admin/.
  • 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).