=== Transleti Translator ===
Contributors: transleti, grupobouso
Tags: translation, multilingual, hreflang, automatic-translation, woocommerce
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 1.9.21
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Automatic WordPress translation with parallel multi-language batches, hreflang sitemap and a visual translation editor.

== Description ==

Transleti Translator is a WordPress translation plugin built on open-source technology. Translations run in parallel batches across all target languages at once, so a multilingual site is fully indexed in minutes rather than hours.

Transleti Translator gives you a flat-rate connection to the Transleti translation API and translates posts, pages, custom post types, WooCommerce products, menus, slugs, SEO meta, and theme strings. A built-in visual editor lets you click on any text in the rendered page and refine its translation in a side-by-side panel.

= Features =

* **Flat-rate pricing** — single subscription, no per-word fees, no per-language tiers.
* **Built on open source** — the plugin itself is GPL, fully auditable, no proprietary lock-in.
* **Parallel translation** — requests fan out to every target language simultaneously. A site with 10 languages translates in roughly the same time as a site with 1.
* **Theme-agnostic** — works out of the box with Elementor, Gutenberg, classic editor, GeneratePress and any standards-compliant theme.
* **WooCommerce ready** — translates product titles, descriptions, attributes and variations.

= Key features =

* **Multilingual sitemap with hreflang** — separate `<url>` entries per language (the format Google explicitly documents) with self-referential hreflang and `x-default`. Compatible with Yoast SEO, RankMath, SEOPress, AIOSEO and the WordPress core sitemap.
* **SEO meta translation** — titles and descriptions for SEOPress, Yoast, AIOSEO and RankMath.
* **Visual translation editor** — open any front-end page in an editor frame, click on any string (titles, paragraphs, menu items, buttons, image alts) and edit its translation in a side panel with live preview.
* **Manual translation editor** — review and refine translations directly in the WordPress post editor for every language.
* **Manual edit protection** — your manual fixes survive re-translation cycles.
* **Slug translation** — translated URLs (e.g. `/es/contacto/`) for clean per-language SEO.
* **Menu translation** — duplicates and translates navigation menus per language.
* **HTML entity and shortcode protection** — prevents corruption of `&copy;`, `[shortcode]`, and similar in translated output.
* **Custom "do not translate" word list** — keep brand names, product codes and acronyms intact across all languages.
* **Language switcher** — widget, block and shortcode in flag, dropdown or text styles.

= Supported languages =

49+ languages including English, Spanish, French, German, Italian, Portuguese (PT/BR), Dutch, Polish, Romanian, Bulgarian, Hungarian, Finnish, Russian, Ukrainian, Arabic, Hindi, Japanese, Korean, Chinese, Thai, Turkish, and more.

= How it works =

1. Install and activate the plugin.
2. Enter your Transleti API key.
3. Choose your default language and the languages you want to publish.
4. The plugin runs a background job that translates posts, menus, slugs and SEO meta automatically.
5. Optionally edit any translation manually from the WordPress post editor.

== Installation ==

1. Upload the `transleti-translator` folder to `/wp-content/plugins/`, or install through the WordPress plugin installer.
2. Activate the plugin via the *Plugins* menu in WordPress.
3. Go to *Settings → Transleti Translator*.
4. Enter your Transleti API key (sign up at https://transleti.com).
5. Select your default language and target languages.
6. Save settings — translation runs automatically in the background.

== Frequently Asked Questions ==

= Is the plugin really fast even with many languages? =

Yes. Translation requests for every target language are fanned out in parallel, so adding more languages does not multiply the wait time. A 10-language site translates in roughly the same time window as a 2-language site.

= Does it work with WooCommerce? =

Yes. Product titles, descriptions, short descriptions, attributes and variations are all translated automatically.

= Does it support Elementor, Gutenberg and the classic editor? =

Yes. Elementor pages translate the underlying `_elementor_data` JSON; Gutenberg parses blocks and translates innerHTML and block attributes; classic posts translate `post_content` directly.

= Will Google index the translated pages correctly? =

Yes. The plugin emits a separate `<url>` element per language in the sitemap (the format Google explicitly documents), with bidirectional hreflang and `x-default`. It also outputs `<link rel="alternate" hreflang="...">` tags in the HTML head.

= Can I edit translations manually? =

Yes. There are two ways: (1) the visual editor, which lets you click on any string in the rendered page and edit its translation in a side panel — useful for menus, buttons, widgets and theme strings that don't live in the post editor; and (2) each translated post is a standard WordPress post you can edit from the admin like any other content. Manual edits are detected and preserved during re-translation.

= What happens if I update the source post? =

The plugin detects content changes via MD5 hashing and queues a re-translation. Manual edits to translations are detected and preserved (unless the source change is structural).

== External Services ==

This plugin connects to the Transleti translation API (`api.transleti.com`) to translate site content into the languages you select. This is required for the plugin to function.

**What data is sent:** the text strings to translate (post content, titles, excerpts, menu labels, slugs, SEO meta, theme strings) along with the source and target language codes and your API key.

**When it is sent:** when the background translation cron runs, when you save a post that needs re-translation, or when you trigger a manual translation from the settings page.

**Service provider:** Transleti — `https://transleti.com`

* Terms of Service: https://transleti.com/terms
* Privacy Policy: https://transleti.com/privacy

No personal data of site visitors is sent to the service. Only the text content you choose to translate.

== Screenshots ==

1. Settings page — connect to the Transleti API and choose languages.
2. Visual translation editor — edit translations on the front-end.
3. Language switcher — flag, dropdown or text styles.
4. Multilingual sitemap output with hreflang alternates.

== Changelog ==

= 1.9.21 =
* Fix: visual editor — clicks on theme menu items (GeneratePress, Astra, Divi, Elementor Pro mega-menus, etc.) now open the translation panel reliably. Listener moved to `window` capture + `pointerdown` so theme menu togglers that call `stopPropagation()` can no longer swallow the selection click.

= 1.9.20 =
* Fix: visual editor now detects menu items in Hebrew, Greek, Hindi, Thai, Georgian and Armenian (menu translation now bails during preview so the renderer can add translatable markers regardless of script).
* Fix: visual editor — clicking on a string with duplicated text on the same page (e.g. a heading and a menu link with the same label) now opens the translation panel for the selected occurrence.
* Fix: ignore RSS feed `pubDate`/`lastBuildDate` strings in the "stuck translations" notice.
* Improvement: automatic cleanup of orphan sentence segments left over from long-paragraph batching.

= 1.9.x =
* New: visual translation editor — click any text in the rendered front-end and edit its translation in a live side panel. Works on menus, buttons, image alts and theme strings.
* New: 49+ languages supported via the Transleti translation API.
* New: HTML entity and shortcode protection across all translation entry points.
* New: "Do not translate" word list (brand names, product codes, acronyms).
* New: SEO meta translation for SEOPress, Yoast, AIOSEO and RankMath.
* Improvement: manual edit protection — your manual fixes survive re-translation cycles.
* Improvement: parallel translation across all target languages.

= 1.4.4 =
* Feature: drag-and-drop reordering of active languages in the Languages tab (also affects the language switcher order).
* i18n: added 503 "pending translation" page strings for 16 additional languages (Lithuanian, Albanian, Azerbaijani, Basque, Bengali, Catalan, Esperanto, Galician, Irish, Kyrgyz, Latvian, Malay, Persian, Slovenian, Tagalog, Urdu).

= 1.4.3 =
* Compliance: wrapped `language_has_translations()` and `find_original_slug()` direct `$wpdb` probes with `wp_cache_get` / `wp_cache_set` (5-minute TTL, `transleti` cache group).
* Compliance: documented every legitimate direct DB call against core meta tables with `phpcs:ignore` comments explaining why the existing core API can't replace them.

= 1.4.2 =
* Hardening: escaped flag-emoji output in the language switcher shortcode (`render_switcher`, `render_language_list`) via `esc_html()`.
* Hardening: every `ob_start()` callback buffer is now explicitly closed via a paired `ob_end_flush()` registered through `register_shutdown_function()` in the same function scope (frontend page buffer, AJAX response buffer, sitemap xhtml-namespace buffer).

= 1.2.1 =
* Hardening: replaced `fopen`/`fread`/`fclose` with `WP_Filesystem::get_contents()` for the diagnostic log reader.
* Hardening: switched all custom-table existence checks to `$wpdb->prepare( 'SHOW TABLES LIKE %s', ... )` (no more single-quote interpolation).
* Hardening: switched several `$_POST` reads on HTML-bearing fields to `wp_kses_post( wp_unslash( ... ) )`; integer reads now use `absint( wp_unslash( ... ) )`.
* Hardening: added explicit nonce checks (`check_admin_referer`/`wp_nonce_url`) to the string-export download link.
* Compliance: removed redundant `load_plugin_textdomain()` call (WP 4.6+ auto-loads translations from the WP.org directory).
* Compliance: documented every legitimate direct-DB query (custom plugin tables) with localised `phpcs:disable`/`enable` blocks.

= 1.2.0 =
* Compliance: removed comparative/superlative marketing phrasing from the readme.
* Compliance: extracted inline `<script>` blocks to enqueued JS files (language switcher, editor preview).
* Hardening: all `$_GET` / `$_POST` / `$_SERVER` / `$_COOKIE` reads now go through `wp_unslash()` plus a context-appropriate sanitiser (`sanitize_text_field`, `esc_url_raw`).
* Hardening: AJAX nonce check in `ajax_empty_language()` now unslashes and sanitises the nonce before passing it to `wp_verify_nonce()`.

= 1.0.6 =
* Removed redundant `load_plugin_textdomain()` call — translations are now auto-loaded by WordPress 4.6+ for plugins hosted in the directory.
* Switched front-end language redirect from `wp_redirect()` to `wp_safe_redirect()` for additional protection against open-redirect attempts.
* Defense-in-depth: explicit allowlist validation for the language storage key before SQL identifier interpolation in the cache-clearing endpoint.
* Packaging: included a `.pot` template in `languages/` so the Domain Path folder is present in the distributed package.

= 1.0.5 =
* New: separate `<url>` entry per language in the sitemap, matching Google's documented hreflang format.
* New: AIOSEO sitemap compatibility (`aioseo_sitemap_post`/`_term`/`_archive_entry`/`_addl_pages` filters).
* Fix: `xmlns:xhtml` namespace now declared in `<urlset>` so `<xhtml:link>` alternates are valid XML.
* Fix: `/sitemap.xml` no longer redirects to `/en/sitemap.xml` when `add_subdirectory_to_default=yes`.
* Fix: sitemap `<loc>` URLs now use the canonical default-language URL instead of the redirecting unprefixed permalink.
* Fix: HTML head and sitemap hreflang codes now match exactly for bidirectional confirmation.

= 1.0.4 =
* Parallel translation crawling — O(1) in number of languages.
* Render substitution fixes for raw `%1$s` placeholders and `[cookie_*]` shortcodes leaking to public pages.

= 1.0.3 =
* HTML entity and shortcode protection in all translation entry points.
* "Do Not Translate" word list.
* Manual edit protection improvements.

== Upgrade Notice ==

= 1.9.21 =
Fixes a visual-editor regression where clicks on theme menu items (GeneratePress, Astra, Divi, Elementor Pro) didn't open the translation panel. Recommended for all users editing menus visually.

= 1.9.20 =
Adds visual-editor support for Hebrew, Greek, Hindi, Thai, Georgian and Armenian menus, plus a fix for clicking duplicated strings. Recommended.

= 1.0.6 =
Maintenance release with security hardening and Plugin Directory packaging fixes. Recommended for all users.

= 1.0.5 =
Important multilingual sitemap fix. After upgrading, purge any sitemap cache from your SEO plugin and resubmit the sitemap to Google Search Console.
