Addons
PerfLocale bundles 20+ integration addons - small modules that teach PerfLocale how to translate content produced by specific third-party plugins and themes. Addons are auto-detected: if you have Yoast active, PerfLocale’s Yoast addon activates; if you uninstall Yoast, the addon goes quiet. You don’t download anything separately.
What’s bundled
Grouped by category:
- E-commerce - WooCommerce (products, variations, categories, multi-currency, checkout flow, emails)
- Page builders - Elementor, Beaver Builder, Bricks, Oxygen (classic + v6 / Breakdance)
- SEO plugins - Yoast, Rank Math, AIOSEO, SEOPress, Slim SEO, The SEO Framework - hreflang, canonical, JSON-LD schema enrichment, no duplicate tags
- Forms - Gravity Forms, Contact Form 7, WPForms
- Custom fields - ACF, Meta Box, Pods - reference-field translation, group-level rules
- Themes - Blocksy, Kadence, Neve (header-builder integration)
How they work
Each addon is a self-contained PHP class that implements the PerfLocale AddonInterface. On boot, the registry iterates every bundled addon, asks is your host plugin active?, and only wires up the ones that answer yes. The overhead for an inactive addon is a single function_exists() / class_exists() check on plugins_loaded.
You can see which addons are currently active at PerfLocale → Addons. The page lists:
- Name, category, and version of the addon
- The host plugin it targets + whether it’s currently detected
- Any capability interfaces the addon implements (schema migrations, uninstall targets, etc.)
- A collapsible Settings section for any addon that declares fields via
get_settings_fields()(renders checkboxes, text inputs, textareas, number inputs, selects, password inputs, and addon-supplied custom widgets from a single declarative array; fields tagged'storage' => 'global'opt out of addon storage and are read straight from the mainperflocale_settingsoption) - An Enable / Disable button on every card
Addon settings — dedicated subtab per addon
Addons declare their configurable surface via get_settings_fields(). For each registered addon with user-editable fields, PerfLocale auto-generates a settings subtab under PerfLocale → Settings → Addons. The card on the Addons listing page links to it via the Manage button. The Addons listing page itself doesn’t embed settings forms — it stays focused on addon status / discovery.
Values are persisted to a single autoloaded option (perflocale_addon_settings) keyed by addon ID. Read from anywhere in PHP: AddonSettings::get( $addon_id, $key, $default ). The save handler skips fields the addon manages itself (e.g. hidden-type fields used as scratch state) so addon code that writes to its own option group is never clobbered by a generic save.
Conditional fields (show_if)
Fields can declare a show_if spec that controls when they render. The conditional JS scans the whole Settings-page DOM, so any settings UI — auto-generated addon subtabs and the legacy WooCommerce subtab — can opt in by adding data-perflocale-show-if='{json}' to its conditional rows; driver inputs are identified by either their canonical data-perflocale-field-name attr or their standard HTML name attribute. Supported shapes:
// Simple equality — multiple keys are AND-ed:
'show_if' => [ 'enable_sync' => true ]
'show_if' => [ 'enable_sync' => true, 'mode' => 'advanced' ]
// Nested with explicit operator:
'show_if' => [
'op' => 'OR',
'rules' => [
[ 'enable_sync' => true ],
[ 'op' => 'AND', 'rules' => [
[ 'mode' => 'pro' ],
[ 'beta' => true ],
]],
],
]The condition is evaluated on the server at render time AND in the browser as the user toggles driver fields (the perflocale-addon-settings-conditional JS is enqueued automatically on the Settings page). No FOUC — the initial render is correct from the server, and the JS keeps it in sync.
WooCommerce ships the largest example: order-email-in-customer-language, inventory sync, multi-currency, and exchange-rate auto-sync are all editable from the WooCommerce addon’s dedicated settings subtab. Full developer reference at Developer Toolkit → Settings.
Where is the on/off state stored?
Three sources of truth, depending on what kind of addon you’re looking at:
- Operator-disabled registry addons — addon ID is written to the autoloaded
perflocale_disabled_addonsoption (an array of strings, capped at 4 KiB). The registry’s boot loop checks this list and skips matching addons. Per-blog on multisite (one option per subsite). - Built-in feature cards (Machine Translation, Translation Glossary, Translation Workflow) — the Enable / Disable button writes to the corresponding Settings flag (
mt_enabled,mt_glossary_enabled,workflow_enabled) inside the mainperflocale_settingsoption. The card’s “Active” / “Disabled” badge reads from the same flag. - Per-addon settings declared via
get_settings_fields()— persisted to the autoloadedperflocale_addon_settingsoption keyed by addon ID, capped at 16 KiB per addon entry.
All three are per-blog on multisite and get swept on uninstall when the operator opts into “Delete all data” (each subsite’s own preference). See Permissions for who can modify them — saving / toggling needs the perflocale_manage_addons capability.
Quarantined addons
If an addon’s boot() method throws an exception 3 times in a row, PerfLocale auto-quarantines it — future boots skip it entirely so a broken addon can’t crash every request. The Addons admin page surfaces a yellow notice listing each quarantined addon with the exact CLI command to clear it once you’ve fixed the underlying problem:
wp perflocale addon reset-quarantine my-addonThe actual exception message is recorded in perflocale_addon_failures + the PHP error log (when WP_DEBUG is on). Reset is also exposed in the registry as AddonRegistry::reset_quarantine($id) for programmatic use.
Building your own addon
If you ship a custom plugin that stores content PerfLocale doesn’t know how to translate, you can write your own addon in ~50 lines of PHP. See Addon System (schema + uninstall) for the full capability-interface reference, or Developer Toolkit for code examples covering settings, i18n, version requirements, dependencies, locks, breakers, and background jobs.
Enabling and disabling an addon
Every addon card has an Enable / Disable button. Clicking Disable writes the addon ID into the perflocale_disabled_addons option and the registry skips it on the next request — no hooks fire, no listeners attach. Clicking Enable drops the ID from the list and the addon boots on the very next request. The bootable-addons transient is flushed automatically, so the change is picked up immediately rather than waiting on the 12-hour TTL.
The Disable button works for both bundled (in-plugin) and external addons. Disabling a bundled addon takes effect immediately and stops its hooks from firing — so only disable one if you genuinely don’t want that integration (e.g. you use WooCommerce but explicitly do not want PerfLocale’s WooCommerce hooks). External addons are those registered via the perflocale/addons/register action.
When you disable an addon, its dedicated settings subtab under PerfLocale → Settings → Addons is hidden too — there’s no point configuring an addon that isn’t running. Re-enable it from the Addons listing card and the subtab comes back automatically. This applies to bundled addons too — e.g. disabling WooCommerce from the listing page hides the WooCommerce subtab even though it’s a built-in subtab, not an auto-generated one.
Built-in features on the Addons listing
Three cards on the Addons listing represent built-in features rather than registry-registered addons: Machine Translation, Translation Glossary, and Translation Workflow. They behave like regular addons from the user’s point of view — the Enable / Disable button toggles them, the Manage link goes to the right settings subtab, the “Active” status reflects the underlying state.
Internally each card’s toggle writes to a different Settings flag (mt_enabled, workflow_enabled, mt_glossary_enabled) instead of perflocale_disabled_addons. The corresponding settings subtab under PerfLocale → Settings → Addons only appears when the feature is enabled, so the navigation stays clean.
If an addon declares a minimum PerfLocale version via the HasVersionRequirement interface and the host plugin is older, it’s skipped — not failed — and a clear admin notice on the Addons page lists which addons need an upgrade.
Who can configure addons
Saving the inline Settings form and toggling Enable / Disable both require the perflocale_manage_addons capability. Administrators have it; the Translator and Editor roles do not. The full capability matrix is at Permissions → perflocale_manage_addons.
When a save or toggle fails
The Addons page shows a red error notice instead of the usual success message when a Save or Enable / Disable request is rejected. Two situations:
- "Could not save settings for X." — the submitted form would push the addon’s entry over the 16 KiB per-addon size cap on the autoloaded
perflocale_addon_settingsoption, or another save was already in flight and the 10-second write lock expired. If you keep seeing this, the addon is trying to store too much data in PerfLocale’s shared settings option — the addon author needs to move bulk state into the addon’s own option or table. - "Could not toggle X." — the
perflocale_disabled_addonslist has hit its 4 KiB cap (only possible after disabling hundreds of distinct addons; in practice this means scripted abuse rather than normal use). Enable a few addons to free space, or check the PHP error log underWP_DEBUGfor the exact rejection reason.
Both caps are deliberate guardrails — both options are autoloaded by WordPress on every request, so capping their size keeps unrelated pages fast.
Related
- Addon System - schema + uninstall contracts for addon authors.
- Developer API - for building custom integrations.
- WooCommerce Guide - the biggest bundled addon walked through in depth.