PerfLocale 1.0.6
— Security hardening, a confirmation for imports from another site, fewer database queries, and a more reliable multisite uninstall
- Security hardening and stricter permission checks.
- Behaviour change: importing a JSON file from another site, or a backup of this site that records a language-specific address, can ask you to confirm this site is a copy of it. Tick the checkbox under Settings → Export & Import, or pass --force. See the Export & Import docs.
- Behaviour change: on WooCommerce stores, a visitor's first page in the site's default language no longer sets the language cookie, so a full-page cache can store those pages. Cart and checkout still work in every language; the perflocale/cookie/skip_redundant_write filter restores the old behaviour.
- Behaviour change: publishing an empty translation of a synced pattern or navigation menu no longer hides it in that language — the original renders instead; publish a translation that holds a non-empty placeholder block to hide one.
- Fixed: previewing an unpublished or private translation showed the published original it shares its slug with. It now previews as itself, except on hierarchical custom post types, which behave as before.
- Fixed: a synced pattern or block-theme navigation menu rendered blank on a language whose translation had been published empty, or with only whitespace. The original now renders instead, as it already did for a missing or draft translation. In long-running processes such as WP-CLI and scheduled tasks, a translation that was unpublished, trashed or emptied after its first use also kept being used; it is now checked again each time.
- Fixed: in the WPForms form builder, the Translations panel's “+ Create” ended on a permission error, administrators included. It now creates the translation.
- Fixed: two requests creating the same translation at the same moment — a double click, two editors, an editor and a background job — made the second one fail with an error, and in a long-running process could, in rare cases, create a duplicate. The second request now waits briefly for the first and returns the translation it created.
- Fixed: “Create Page Translations” (WooCommerce) and “Create Taxonomy Translations” could save a page title or term name in the administrator's own language instead of the target language. When the target language had no WordPress language pack installed, WordPress declined to switch to it, and the lookup answered in the administrator's language, which was then saved as the translation. A language WordPress cannot switch to now counts as having no local translation, so machine translation or the original title is used, as for any other untranslated title.
- Fixed: the suggested translations on the Strings screen — the grey hints in empty translation boxes, taken from installed translation files — showed the administrator's own language for a language that has no language pack installed. Such a language now shows no hints.
- Fixed: the Jobs screen showed “Not scheduled” for a recurring task while it was running, because Action Scheduler creates the next run only after the current one finishes. It now shows “Running”.
- Fixed: on category, tag and author archives, the block-reference cache warm-up read whichever post happened to have the same ID as the archive's term or author, doing work for content that was not on the page. What the page displayed was not affected.
- Fixed: deleting a language left a cached “this site has translated slugs” flag behind in a persistent object cache such as Redis, so a site whose last translated slugs went with that language kept running slug lookups that could find nothing.
- Fixed: on multisite, deleting the plugin from a large network could stop part-way through a request, leaving the remaining sites untouched with no record of where it stopped — and a site whose purge was interrupted came back as though it had chosen to keep its data. The uninstall now works through the network in batches, notes where it stopped, carries on from there the next time you delete the plugin, and keeps each site’s own “Delete data on uninstall” choice intact through an interruption.
- Fixed: on multisite, one site failing during a network activation stopped every site after it from being set up, while the plugin still reported itself as network active. Activation now records the failure and carries on to the remaining sites.
- Fixed: on multisite, a site visited earlier in the same request could be rendered with the language detected on that earlier visit instead of looked up afresh, and a loop over more than about thirty sites logged a warning that blamed another plugin for unbalanced switch_to_blog() calls.
- Performance: fewer database queries on front-end pages, feeds, sitemaps and REST requests, with the same output. Measured against 1.0.5 on a WooCommerce test site using Redis, all 28 front-end, feed, sitemap and REST requests we compared ran 2 to 8 fewer queries — the English home page went from 10 to 5, sitemaps from 3 to 1. On a test site with 10,000 posts, pages ran 4 to 5 fewer queries; on a multisite network, 1 to 2 fewer. Admin screens run the same queries as before.
- Performance: block-theme global styles, templates and template parts no longer have their translated slugs looked up. WordPress loads those records on every page of a block theme, and nothing on those paths builds a link from them.
- Performance: category and tag slugs are looked up only when a link to the term is actually built. WooCommerce and block themes read terms on every listing without linking most of them, and each read used to trigger a slug query whose result nothing used. A 12-product test listing went from 33 queries to 18; the 12 slug lookups left are needed, because WooCommerce's Store API builds category and tag links for each product.
- Performance: WooCommerce's shop, cart, checkout, my-account and terms page IDs are read through WordPress's option cache instead of a separate database query: from Redis on sites using the Redis Object Cache plugin, 2.0 or later (one query fewer per request), and from WordPress's own cache on sites without a persistent object cache (three fewer, because WooCommerce's own re-reads of those settings are answered too). Other object caches keep the single query 1.0.5 used, because some of them would turn it into several cache round trips.
- For developers: DataImporter::import() accepts an $options array; its allow_foreign_ids key does what --force does. wp perflocale import gained --force.