=== BallesDev LingoPress ===
Contributors: ballesdev
Tags: multilingual, translation, ai, seo, languages
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.0
License: GPL-3.0-or-later
License URI: https://www.gnu.org/licenses/gpl-3.0.html

Multilingual content for WordPress with AI-powered, context-aware translations. SEO-first.

== Description ==

BallesDev LingoPress makes your WordPress site multilingual with a proven data model (languages and translation groups as taxonomies, no custom tables) and adds AI translation that actually understands your content. Every feature is included — there is no paid tier, license key or locked functionality.

**Multilingual core**

* Languages with directory-based URLs (/es/, /en/) and automatic rewrite rules.
* One post per language, linked as translation groups.
* Automatic hreflang tags, language-aware 301 canonicals and sitemap support.
* Language switcher as a Gutenberg block, shortcode, widget, menu item or PHP function.
* Menus per language, media translation with shared files, string translations.
* Template translations for block themes (FSE): each language gets its own copy of your templates and template parts.
* REST API: `lang` and `translations` fields on wp/v2, collection filtering with `?lang=`.

**AI translation (optional)**

* On WordPress 7.0+, LingoPress uses the AI provider you connected in **Settings → Connectors** through the WordPress AI Client — no extra API key in LingoPress.
* Or bring your own key: Claude (Anthropic), Gemini (Google), OpenAI (ChatGPT) and GroqCloud providers, selectable in settings (also on WordPress 6.5–6.9).
* Context-aware prompts: the AI reads the whole content, your site description and your glossary before translating a single word — so an ambiguous word like Spanish "muñeca" becomes "wrist" on a fitness blog, never "doll".
* Glossary with hard terminology rules.
* One-click translation from the editor, bulk translation with a background queue, automatic retry with backoff on provider saturation, and outdated-translation detection with one-click re-translation.
* Long content is automatically split into block-aligned chunks.
* Every AI translation is created as a draft for human review. Nothing is published automatically.

The multilingual features work fully without any API key. AI translation is an optional extra that only runs when you ask for it — see "External services" below.

**Developer friendly**

* Public API: `lingopress_set_post_language()`, `lingopress_get_post()`, `lingopress_the_languages()`, `lingopress_register_string()` and more.
* Hooks: `lingopress_language_defined`, `lingopress_ai_system_prompt`, `lingopress_ai_provider`, `lingopress_switcher_items`, `lingopress_sync_post_meta`.
* Polylang importer included (languages, content languages and translation groups).

== External services ==

LingoPress can translate your content with an AI provider of your choice. This is optional: no request is made to any AI service until a provider is set up — a connector in **Settings → Connectors** (WordPress 7.0+) or an API key in **LingoPress → AI translation** (or its constant in `wp-config.php`) — and a user with editing permissions starts a translation — from the post editor, the bulk action, the Queue, the Templates tab or the "Translate missing strings with AI" button. Queued jobs run in the background through WP-Cron, but only jobs that a user explicitly queued.

Only the provider selected in the settings receives data. Each request sends the text being translated (post title, content and excerpt; a theme template; or the registered strings), the source and target languages, your site name and tagline, the "Site context" and glossary settings, the post type and the names of the post's categories and tags, together with your API key to authenticate. No other site or visitor data is sent.

* **WordPress AI Client (Settings → Connectors)** — used when the provider is set to "WordPress (Connectors)". LingoPress hands the request to WordPress core, which sends it to the AI service the site owner connected (for example Anthropic, Google or OpenAI) under that service's terms and privacy policy; LingoPress itself does not contact any external server in this mode.
* **Anthropic Claude API** (`api.anthropic.com`) — used when the provider is set to Claude. [Terms of service](https://www.anthropic.com/legal/commercial-terms), [Privacy policy](https://www.anthropic.com/legal/privacy).
* **Google Gemini API** (`generativelanguage.googleapis.com`) — used when the provider is set to Gemini. [Terms of service](https://ai.google.dev/gemini-api/terms), [Privacy policy](https://policies.google.com/privacy).
* **OpenAI API** (`api.openai.com`) — used when the provider is set to OpenAI. [Terms of service](https://openai.com/policies/business-terms/), [Privacy policy](https://openai.com/policies/privacy-policy/).
* **GroqCloud API** (`api.groq.com`) — used when the provider is set to Groq. [Terms of service](https://groq.com/terms-of-use), [Privacy policy](https://groq.com/privacy-policy).

== Installation ==

1. In your WordPress dashboard go to **Plugins → Add New**, search for "BallesDev LingoPress", then install and activate it.
2. Go to **LingoPress → Languages** and create your languages (the first one becomes the default).
3. Optional: for AI translation, connect a provider in **Settings → Connectors** (WordPress 7.0+) or add your own API key under **LingoPress → AI translation**; then describe your site in "Site context" and add glossary rules.
4. Assign a language to existing content, or run the Polylang importer if you are migrating.

The **Getting started** tab walks you through these steps and shows what is still pending.

== Frequently Asked Questions ==

= Do I need an AI provider to use LingoPress? =

No. Languages, URLs, hreflang, the language switcher, menus, media and string translations all work without any API key. AI translation is optional.

= Does the AI publish translations automatically? =

No. Every translation is created as a draft, linked to the original, for a human to review and publish.

= What happens if the AI provider is saturated? =

Jobs are retried automatically with increasing backoff. You can also retry failed jobs manually from LingoPress → Queue.

= Where do the API keys live? =

With the "WordPress (Connectors)" provider (WordPress 7.0+), in **Settings → Connectors**: WordPress manages the credentials and LingoPress stores none. With your own key, in the plugin settings, or preferably in `wp-config.php` via the `LINGOPRESS_ANTHROPIC_API_KEY`, `LINGOPRESS_GEMINI_API_KEY`, `LINGOPRESS_OPENAI_API_KEY` or `LINGOPRESS_GROQ_API_KEY` constants (constants take precedence).

= Can I migrate from Polylang? =

Yes. LingoPress ships an idempotent importer that migrates languages, post/term languages and translation groups.

== Changelog ==

= 1.0.0 =
* First release on WordPress.org, as BallesDev LingoPress.
* New "WordPress (Connectors)" AI provider: on WordPress 7.0+ translations use the AI provider configured in Settings → Connectors through the WordPress AI Client (default on new installs). Claude, Gemini, OpenAI and Groq with your own key remain available.
* Public API and stored data use the `lingopress_` prefix, e.g. `lingopress_get_post()`, `lingopress_set_post_language()`.
* Admin styles and scripts load only on LingoPress screens; inline scripts moved to enqueued files.
* Translations are now delivered through translate.wordpress.org.
* Removed the licensing system and the self-hosted update channel: every feature is free and updates are delivered through WordPress.org.
* Security hardening: AI provider responses are sanitized before they are saved (posts, templates and string translations), and the language switcher output is escaped where it is printed.

= 0.10.2 =
* The Translate button on the Templates tab now shows real progress from the very first second: it fetches the total number of steps instantly ("Translating 1 of 3") and pulses animated dots while each step is running, so a long AI call never looks frozen.

= 0.10.1 =
* Template translations no longer hit server connection timeouts: the work now runs in short steps (one chunk per request) with live progress on the Translate button, and it automatically resumes where it left off if the connection drops mid-way. Fixes the "request takes too long, timed out by the server" error on hosts with strict connection limits (e.g. LiteSpeed).

= 0.10.0 =
* Settings redesign: the LingoPress admin is now a full-width product UI — brand header with your site's languages at a glance, modern tabs ordered by workflow, cards, status pills, toggle switches and friendly empty states across all eight tabs.
* Getting started: every step now shows its real status (permalinks, languages, AI provider, site context, translated content, license), with a setup-progress card and the next step highlighted.
* String translations: spreadsheet-style grid — the Original column stays frozen while you scroll, language columns are labeled with locale chips, and the save bar sticks to the bottom.
* Queue: pending/done/errors tiles, clearer status pills and an empty state that explains how to fill the queue.
* Accessibility and polish: AA-verified contrast, keyboard focus rings, RTL-ready layout, reduced-motion support; admin styles now refresh automatically after every update (no stale-cache look).
* Spanish translations (es_ES and es_AR) are complete, and es_ES now consistently uses peninsular Spanish.

= 0.9.0 =
* Template translations (FSE): each language gets its own copy of your templates and template parts — AI-translated from the default language (patterns expanded, block markup preserved) and fine-tuneable visually in the Site Editor. The right version is served per language URL with zero per-block runtime cost; hreflang, canonicals and URLs untouched. New Templates tab with per-language status (missing / up to date / outdated) and one-click (re)translation.
* Block-string discovery from 0.8.0 was replaced by template translations (a single, document-level model); classic String translations remain for PHP-registered strings, with the AI fill button.
* AI providers: request timeout raised to 300s (large template chunks on slower models timed out at 120s).

= 0.8.0 =
* Block text translations (FSE): every text in your templates, template parts and patterns (Site Editor) is now discovered automatically and listed under String translations — headings, paragraphs, lists, buttons and navigation labels. Translations apply at render time, closing the classic FSE gap where editing a section froze it in one language. Post content is untouched (it translates per linked post, as always).
* String translations: new "Translate missing strings with AI" button fills every empty field for all languages using your configured AI provider.

= 0.7.3 =
* Performance: memoized hot-path lookups (translated post types/taxonomies, language URL pattern), batched term-language cache priming and precached translation data in admin list tables — fewer queries on every page load.
* Queue hardening: an atomic processing lock prevents duplicated batches, jobs are persisted one by one against fresh state (jobs enqueued during a long batch can no longer be lost) and the finished-job history is bounded.
* Fixes: REST API detection under PATHINFO permalinks and for URLs whose slug contains "wp-json"; the version-upgrade routine now runs at the right time (init) and detects upgrades on databases missing the version key; license activation/deactivation notices now display; saving settings writes the option once instead of once per field.
* Cleanup: the four AI providers share a common base class; uninstall now removes all plugin data (queue, license, caches, meta and user preferences).
* Developer: new `lingopress_upgraded` and `lingopress_options_saved` hooks.

= 0.7.2 =
* Plugin icon: the LingoPress brand icon now shows on the Plugins and Updates screens (served through the update manifest).

= 0.7.1 =
* Plain-language pass: the onboarding steps, settings help, notices and messages were rewritten so a non-technical user understands them (e.g. "web addresses" instead of "permalinks", an API-key hint, softened slug/locale/attachment jargon). Spanish (es_ES, es_AR) updated to match.

= 0.7.0 =
* AI reasoning control: pick the reasoning effort (none/low/medium/high); the field only shows for models that support it (gpt-oss, Qwen3, GPT-5/o-series, Gemini 2.5, Claude). Defaults to low to save tokens and latency and keep the output clean.
* Model picker: choose the translation model from a per-provider dropdown of text-capable models, or type a custom one.
* New "Getting started" onboarding tab (default landing) with a step-by-step, non-technical setup guide.
* String translations moved from a separate submenu into a tab.
* Full Spanish (es_ES, es_AR) translation of the admin UI.

= 0.6.1 =
* Language locale selector: pick from the WordPress translations list; name, slug and RTL auto-fill.

= 0.6.0 =
* Per-domain licensing: License tab, activation against the self-hosted license server, licensed update channel.

= 0.5.0 =
* Self-hosted updates via the Update URI header (WordPress update channel, no wordpress.org).
* Clearer field descriptions for String translations and the AI Glossary.
* User documentation set under docs/.

= 0.4.0 =
* New OpenAI (ChatGPT) translation provider with strict structured outputs.
* New GroqCloud translation provider (OpenAI-compatible API, JSON mode).
* Language UI for categories and tags (forms, columns, translation linking).
* Automatic retry with backoff for transient AI provider errors.
* Long content is split into block-aligned chunks for translation.
* Editor AI translation now goes through the queue with timeout protections.
* Object-term cache used everywhere (fixes N+1 queries in list tables).
* readme.txt, POT file and Plugin Check compliance.

= 0.3.0 =
* home_url filtered per language: theme logo/home links keep the current language.

= 0.2.0 =
* Language Switcher block preview made inert (Site Editor crash fix).
* Metabox: translations list syncs with the language dropdown; draft-first hint on new posts.
* Tabbed settings, per-provider key fields, translation queue screen.

= 0.1.0 =
* Initial release: multilingual core, frontend SEO, admin, REST, navigation, AI providers, Polylang importer.

== Upgrade Notice ==

= 1.0.0 =
First WordPress.org release. Licensing has been removed: all features are free and updates now come from WordPress.org.
