← All releases

PerfLocale 1.0.7.3

- Machine translation that keeps block markup intact, more complete and safer Export & Import, translated templates that use their language's menus and patterns, safer Polylang imports, and SQLite fixes

  • Security hardening.
  • Machine translation: before a machine translation of a post is saved, its block structure is compared with the source: the same blocks in the same order, every block comment complete, and block settings that can be read. When it does not match, the result is not saved: a bulk translation, wp perflocale translate and the REST API report the item as failed with the reason, and an existing translation keeps its content. WooCommerce variation descriptions are checked the same way. The provider has already translated the text when the check runs, so a refused result still counts toward the monthly character limit and the provider's bill.
  • Machine translation: block comments are sent to the provider as markers with no text in them and put back unchanged, so the provider never receives a block's settings. Text a block keeps only in its comment, such as a label, is sent on its own and still translated, unless the comment holds a shortcode. Button blocks keep their <button> element.
  • Machine translation: when + Create with Auto-Translate on Create cannot machine-translate the new translation (the check refuses the result, the provider fails, the original is password-protected, or the request limit is reached), the translation is still created as an untranslated copy of the original, and the screen it opens on says why, for example "Machine translation was not saved: The machine translation returned no translation. This translation is an untranslated copy of the original."
  • Machine translation: when Auto-Translate on Publish cannot save a machine translation, the post's edit screen shows the reason once, on the next visit of the person who published the post (or of its author, when a schedule or WP-CLI published it), and names the languages whose translations were not changed. A password-protected post is not sent, and the notice says so.
  • Machine translation: a translation someone edits while its machine translation runs keeps their edit; the machine translation is not saved, and the reason is shown.
  • New: wp perflocale damaged-blocks lists translations whose block markup was damaged: escaped or cut-off block comments, unbalanced blocks, and blocks that lost settings their source block has. It changes no content or settings, and exits with status 2 when it lists translations, 0 when it lists none and 1 when it cannot run or cannot read the database. For a translation nobody edited by hand, translating its source again with wp perflocale translate --post-ids=<source_id> --to=<language> replaces the damaged content.
  • Behaviour change: in HTML content (post content, and custom fields and strings that hold HTML), machine translation holds back the tags of every registered shortcode, attributes included, and puts them back unchanged. The text a shortcode encloses is still translated, and so is a [caption] shortcode's caption. Titles, excerpts, plain-text fields and strings without HTML are sent as text, shortcodes included. The new perflocale/mt/text_shortcodes filter sends a shortcode's attributes when they hold visible text.
  • Behaviour change: custom fields whose name contains token, password, api_key, apikey, secret, license or licence as a whole word, such as stripe_token or my_license, are never sent to machine translation. They are still copied between languages. The perflocale/translation/dangerous_meta_patterns filter receives 'copy' or 'machine_translation' as a second argument, so a site can send such a field when it holds no secret.
  • Site Editor: translated templates and template parts use their language's menu and synced pattern translations. PerfLocale points them there when a menu, pattern, template or template part translation is created, linked, imported or restored from a PerfLocale export, so editing a menu or pattern inside Header (de) edits the German one. A menu or pattern you chose yourself is kept, also when you switched back to the original on purpose. Deleting or trashing a menu or pattern translation brings the original back in those places, and restoring it from the Trash points them at the translation again. A menu or pattern that moves to another language is no longer used by the templates of the language it left. PerfLocale updates the stored template or part directly, which makes no revision.
  • Site Editor: templates and template parts translated before this update are updated once by a background job, started by the first admin page view of a user who may edit the theme. Its row on the Jobs page counts what it read and updated, and the new wp perflocale template-refs-backfill command runs it again. What visitors see does not change: their pages already show the translations.
  • Site Editor: in a translated template or template part, a Navigation block or synced pattern that is still shared with the original language says so in its block settings, with a link to its translation or a button to create it. The Translations panel offers Publish on a draft or pending menu translation.
  • Site Editor: when a menu, pattern or template part translation is created for one that many templates use, the first templates are updated at once and the rest by a background job with its own row on the Jobs page.
  • Export & Import: an export carries four new sections: Media (each language's alt text, caption and description of a media item, and a post's featured image per language), Menus (a classic menu's language and its pairing with its translations), Item flags (Independent across languages, the hreflang and sitemap exclusion, and an order's language) and Add-on data (such as the Gravity Forms translations, imported when Gravity Forms and its PerfLocale add-on are active). Languages also carries the redirects of renamed language codes, Settings the webhooks, and Roles & Capabilities the Translator role's permissions; webhooks and permissions are applied by a Replace import only. Webhooks travel without their secrets: a webhook this site already has keeps its secret, any other gets a new random one, and the import says how many to register again.
  • Export & Import: the export and import screens have one Add-on data checkbox for all add-ons together, and an add-on can give its data a checkbox of its own. wp perflocale import --addon-data makes the same choice. Add-on data whose add-on is not active on this site is skipped and named in the report.
  • Export & Import: large files upload in pieces through the Export & Import screen, so a file larger than PHP's upload limit imports from the screen, up to 512 MB by default. When the server or a proxy refuses a piece as too large, the screen sends it again in smaller pieces. The importer reads every file in pieces, on the screen, with wp perflocale import and with wp perflocale network-import, so a file's size does not decide the memory an import needs, and a genuine export within the size limit is not refused for having many rows. The export screen warns when a full export would be larger than the site can import there.
  • Export & Import: a Merge import never changes this site's default language: the file's default language is added as an ordinary language. A post or term that already has a language here keeps it, and a translation link that would give it a second one is left out and counted. A Replace import always leaves exactly one default language, clears only the sections the file carries, and keeps this site's own domains, provider addresses, uninstall choice and paused queue, naming any whose value in the file differed.
  • Export & Import: a Replace import refuses a file in which more than half of the rows that name a post, term or order by ID name a different one on this site, since such a file most likely comes from another site; nothing is changed. A row whose post or term changed since the export but is still recognised, for example by its GUID or slug, is imported, and the report says what it was recognised by. Every row an import leaves out is counted and named with its reason.
  • Export & Import: a Replace import that fails changes nothing, its settings included, even when the process is stopped part-way. An import that adds or removes languages rebuilds the language URL prefixes. When a settings import cannot change a provider's address because the network administrator sets that provider's key, the import report names it.
  • Export & Import: an import's own writes no longer start Sync Fields mirroring, so a Merge or Replace import gives each post the values the file holds. The new perflocale/import/sync_fields_mirroring filter turns mirroring on for imports.
  • Uninstall: a delete-all-data uninstall on a site with a persistent object cache also clears the cached copies of the post, term and user meta it deletes, so a reinstall followed by a Merge import restores every row of the file. It also removes Oxygen's access setting for the Translator role.
  • Behaviour change: a PO import in Replace mode is rolled back entirely when a database write fails, as a data import in Replace mode is, and says so; nothing is changed. It used to skip the failing entry and keep the rest.
  • XLIFF import: errors come one per post and cause, naming the post ID and the file's unit IDs, for example "Post 999 (units post-999-title, post-999-content, post-999-excerpt): this post does not exist on this site. The file may come from another site, or the post was deleted." A post's title is shown only when you may edit that post. A translation that could not be saved or created is written to the PHP error log, also without WP_DEBUG.
  • Jobs: the row of a finished or canceled bulk translation, site-wide translation, bulk string translation or strings scan shows its first error, shortened, with the whole text when you point at it. An import that is refused or fails shows as failed, with the reason beside its row, and is not run again on its own. After you queue a bulk machine translation, an export, an import or a migration, the Jobs page says it was queued.
  • Polylang import: a post or term you already linked to translations in PerfLocale is never moved out of its translation group or replaced: the Polylang translation set is left as it is and listed with examples. A linked post or term that PerfLocale has in another language keeps PerfLocale's language and is listed; the new perflocale/migration/language_conflict_policy filter gives it Polylang's instead. A post or term alone in its group, whose language no earlier import set, takes Polylang's language, and the import lists those whose earlier language was not the default. Items whose post or term no longer exists, or whose language has no PerfLocale language, are listed too.
  • Polylang import: in the admin, an import with items left out shows a yellow Needs attention notice instead of the green success notice, and one that could not read or write part of the data shows a red error; running it again imports the rest. String translations PerfLocale has no place for, menu-location conflicts, Price Sync and translatable-type messages and the language check's findings are shown as notices, not counted as errors. Records of an earlier Polylang or WPML import that no longer match their translation set are not reused.
  • Polylang import: a canceled import stops within about half a minute; it no longer reads all its remaining pages first.
  • Behaviour change for scripts: wp perflocale migrate polylang ends with Warning: instead of Success: when it left items out (exit status 0), and the dry run of any import (WPML, Polylang, TranslatePress) that finds problems which do not block it ends with a warning instead of Success. A script that looks for Success: should check the exit status instead: 0 when the import finished, 1 when it did not.
  • Imports from WPML and TranslatePress: a batch is never left half imported. When a database write in it fails, or the database ends its transaction (for example after a deadlock), the batch is rolled back and written again, or reported as failed.
  • New: wp perflocale stock-drift lists WooCommerce products whose language copies hold different stock. It compares every product and variation that manages its own stock and is not excluded from the sync, changes no stock, content or settings, and exits with status 2 when it finds a difference and 1 when it cannot run or cannot read the database.
  • WooCommerce: an order placed while an attribute term is being linked to its translation reduces the stock of the matching variation in each language.
  • Meta Box: on translated pages, Meta Box blocks no longer show another language's cached output on sites with a persistent object cache; post and taxonomy_advanced fields printed through rwmb_the_value(), the [rwmb_meta] shortcode, MB Blocks templates, MB Group and the page-builder integrations show the translation; cloneable multiple reference fields keep their structure.
  • Pods: relationship fields that point to posts or terms show the translations on translated pages, also in the [pods] shortcode, magic tags, the Pods Field block and display().
  • Bulk and site-wide machine translation, wp perflocale translate and the importers check between items whether other requests changed languages, settings or slugs, and continue with the current values. When the target language is deleted during the run, the new translations the run created for it in its current batch of up to 500 posts are deleted again and reported as failed; translations from batches the run already finished, and translations that existed before the run, are kept, and the remaining posts fail. When the language is deactivated, the remaining posts fail and the translations already written stay.
  • Languages: a language delete or rename and a settings save at the same moment no longer overwrite each other's change. A language delete that cannot finish is rolled back and reported as failed.
  • Sync Fields: when several saves of one post's translations happen at once, a Sync Field change is no longer dropped; under extreme contention, a change still pending is copied by the next save. PerfLocale's own internal fields cannot be added to Sync Fields, and the Settings screen names any it left out. A new translation no longer copies the original's internal machine-translation error records.
  • Strings: the machine-translation confirmation dialog and the POST /machine-translate/estimate route count only the strings one run translates (5,000 by default).
  • Editors of a taxonomy with its own permissions can set a term's language on the term screens.
  • SQLite (WordPress Playground and hosts that use the SQLite Database Integration): translations are marked Needs Update when their original changes; the strings scan gives every string its own translation group, and a one-time repair fixes the groups an earlier scan shared between strings, as a background job in small steps (wp perflocale db-migrate runs it at once); the machine-translation safety switch trips after repeated failures; the redirect of a renamed language code is saved; stuck locks, jobs and interrupted imports are taken back; PO import counts are correct; rows an import already has are skipped instead of reported as errors; and stock sync skips its follow-up work for product copies whose stock status did not change.
  • Site Health: the check for stale translation files compares each language's translations with that language's own files and uses one clock, so it no longer reports files as stale after a save or PO import that only rebuilt some languages; it names the stale languages.
  • Accessibility: the import file field, the language filters on the post and term lists and the language select on the Menus screen have names that screen readers announce.
  • Language Switcher widget: its name and description are translated when it is placed through a Legacy Widget block or rendered directly by a theme.
  • Dashboard: Clear Cache clears PerfLocale's caches only, every link cache included; on a site with a persistent object cache it no longer empties the cache of every other plugin. Clear Cache and wp perflocale cache flush keep the notices still waiting to be shown, circuit breakers and machine-translation rate-limit windows.
  • Admin: the language filter on term lists, the bulk tools on the Settings screen, the Strings screen's machine-translation dialog and the other PerfLocale admin scripts load from script files instead of inline code. The post edit screen no longer loads the unused language badge script, which saves a database read per edit screen.
  • Performance: cart and checkout load less of the stock-sync code, Beaver Builder sites translate the language switcher module's settings labels only where they show (the builder, admin, REST and WP-CLI), and the Languages screen makes fewer reads when every language pack is installed. Large sites do less work in several places: the core sitemaps read the translations of a page's posts and terms in batches, also for taxonomies over the priming limit and on every page of a multi-page sitemap build; ACF Relationship, Post Object and Taxonomy fields with several values, Meta Box reference fields and Pods relationship fields load their translations in batches; reusable blocks and patterns warm their caches with fewer reads; a cold translation lookup finds sibling translations through an index; the XLIFF export keeps one chunk of posts in memory instead of all of them; the Polylang import compares WooCommerce prices with flat memory and reads translation sets a page at a time; the strings repair writes missing links 200 per statement; and the machine-translation placeholder check and restore run in one pass over the text.
  • New WP-CLI: wp perflocale damaged-blocks, wp perflocale stock-drift and wp perflocale template-refs-backfill. wp perflocale import takes --addon-data and --batch-size, and wp perflocale network-import takes --batch-size, and wp perflocale network-import accepts --yes, as documented, to run without the confirmation prompt. wp perflocale damaged-blocks and stock-drift stream their rows, so their memory stays flat on large sites.
  • New filters: perflocale/mt/text_shortcodes, perflocale/migration/language_conflict_policy, perflocale/import/batch_size, perflocale/import/keep_target_settings, perflocale/import/upload_piece_bytes, perflocale/import/upload_quota, perflocale/import/sync_fields_mirroring, perflocale/data_registry/entries (an add-on, Pro or another plugin declares the data it stores, so export, import, translation copies and Sync Fields handle it, optionally with its own export and import checkbox), perflocale/data_registry/is_secret and perflocale/strings/sqlite_repair_batch_size. New action: perflocale/cache/refreshed.
  • Changed filters: perflocale/mt/wp_ai_client_prompt receives the destination format ('html' or 'text') as a fifth argument; perflocale/translation/dangerous_meta_patterns receives 'copy' or 'machine_translation' as a second argument; perflocale/import/quality_limits accepts max_section_bytes, max_config_bytes, max_captured_bytes, max_top_level_members and max_data_members, and its default row limit follows PHP's memory limit and the import size limit, never below 500,000 rows; perflocale/import/max_file_bytes defaults to 512 MB.