Wpml compatibility audit
Skill Lonsdale201/wp-agent-skills/wpml/wpml-compatibility-audit
Audit whether a WordPress plugin or classic theme is WPML-compatible end to end. Use when asked "is this plugin WPML compatible?", "why does this shortcode/string/page not translate?", or when code has wpml-config.xml, stored page/product/term IDs, get_permalink/home_url, shortcode attributes, get_option option strings, custom tables, WooCommerce order/product data, emails/PDFs/background jobs, wpml_register_single_string, wpml_translate_single_string, wpml_object_id, wpml_permalink, or wpml_switch_language.From its SKILL.md
npx -y skills add Lonsdale201/wp-agent-skills --skill wpml-compatibility-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.3 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it
WPML compatibility audit
Use this to produce a verdict on a plugin/theme's WPML compatibility. This is a workflow skill: it tells you what to inspect and how to classify problems. Use the narrower WPML skills for implementation details once a failing area is identified.
Compatibility verdicts
Report one of these:
- Compatible: static gettext, dynamic strings, stored IDs, queries, URLs, and background render paths work in the current language or deliberately snapshot original data.
- Partially compatible: most static strings work, but one or more dynamic strings, stored IDs, shortcodes, emails/PDFs, or custom tables need fixes.
- Not WPML-compatible: core user-facing flows hard-code one language or one object ID, or rely on direct meta/option strings with no translation path.
- Not testable: required WPML add-ons or plugin runtime dependencies are missing; still report source-level risks.
Audit workflow
- Identify the multilingual surface:
- Is WPML core active/installed?
defined( 'ICL_SITEPRESS_VERSION' ). - Is String Translation installed?
defined( 'WPML_ST_VERSION' )orwpml_is_st_loaded(). - If String Translation is missing, dynamic option/admin strings are not runtime-testable; the hook form still degrades to original text.
- Is WooCommerce Multilingual relevant for products/orders?
- Does the plugin also claim Polylang/TranslatePress compatibility?
- Is WPML core active/installed?
- Separate static gettext from dynamic strings:
- Static UI strings using
__(),_e(),esc_html__(), etc. are normal WordPress i18n. Check text domain, load timing,.pot,.po/.mo, and JS translations. - DB/admin-entered strings need WPML String Translation. They must be registered and translated on every output path.
- Static UI strings using
- Inventory stored object IDs:
- Options/meta/custom tables holding page, post, product, variation, term,
attachment, menu, or form IDs need runtime resolution with
wpml_object_idor a correctwpml-config.xmldeclaration. - URLs derived from those IDs need
get_permalink( $translated_id )orwpml_permalink.
- Options/meta/custom tables holding page, post, product, variation, term,
attachment, menu, or form IDs need runtime resolution with
- Inspect shortcode/block behavior:
- A shortcode's PHP-generated output still needs runtime string/ID handling.
- Shortcode attributes/content stored inside page content need
wpml-config.xml<shortcode-list>or rich<shortcodes>config when WPML should expose them to translators. - Block attributes need
<gutenberg-blocks>config when not covered by normal block translation.
- Inspect queries:
- Default WP queries usually follow the current WPML language.
- Queries for another language need
do_action( 'wpml_switch_language', $lang )and restore withnull. - Custom SQL/custom tables are not language-filtered by WPML; they need an explicit language column, translated joins, or deliberate snapshot logic.
- Inspect WooCommerce paths:
- Historical order item snapshots should usually stay as purchased.
- Current product/category/tag links or settings should resolve translated IDs before display.
- Product/category/tag meta compatibility belongs in
wpml-config.xmlcustom-field/custom-term-field declarations.
- Inspect async/non-page rendering:
- Emails, PDFs, cron, REST, exports, and webhooks do not automatically have the same language context as the frontend request.
- Store the request language when creating records, then switch language while rendering language-sensitive output and restore afterward.
Dynamic string checklist
Find option reads/writes, settings textareas, admin-entered labels, and template data that comes from the database.
WPML core exposes wpml_is_st_loaded() as defined( 'WPML_ST_VERSION' ).
The actual handlers are in the String Translation add-on: ST 3.5.3 registers
wpml_register_single_string in inc/functions.php and filters
wpml_translate_single_string with a 5-argument callback.
Correct pattern:
do_action( 'wpml_register_single_string', 'my-plugin', 'button_label', $value );
$label = apply_filters(
'wpml_translate_single_string',
$value,
'my-plugin',
'button_label',
$language_code // optional; omit for current language
);
Rules:
- Registering alone is not enough; output must call
wpml_translate_single_string. - Passing an explicit language is useful for emails, PDFs, exports, and jobs rendered outside the original frontend request.
- The hook form degrades safely when String Translation is absent.
- Legacy
icl_register_string()/icl_t()must be guarded withfunction_exists(). - Keep context and names stable. Changing them orphans existing translations.
- Prefer
<admin-texts>inwpml-config.xmlfor fixed option keys, but remember it needs String Translation.
Stored ID checklist
Flag every stored ID and decide whether it is a snapshot or a live reference:
- Live page/post/term/product ID for display: resolve with
wpml_object_id. - Live URL: use translated ID or
wpml_permalink. - Admin edit links and historical order/case snapshots can usually stay in the original object/language.
- Asset enqueueing based on
is_page( $stored_page_id )must also account for the translated page ID.
Typical page-option pattern:
$page_id = (int) get_option( 'my_page_id' );
$page_id = (int) apply_filters( 'wpml_object_id', $page_id, 'page', true );
$url = $page_id > 0 ? get_permalink( $page_id ) : '';
wpml-config.xml checklist
Check whether the plugin ships wpml-config.xml in the plugin root. If absent,
decide whether it needs one.
String Translation parses config through wpml_parse_config_file /
wpml_parse_custom_config. <admin-texts> entries are imported by ST and can
attach option_{$option} filters for translated option values and nested ID
translation. Without ST, <admin-texts> does not provide translated output.
Usually declare:
- CPTs/taxonomies the plugin owns:
<custom-types>/<taxonomies>. - Product/page/post/term meta that must copy/translate:
<custom-fields>/<custom-term-fields>. - Option strings:
<admin-texts>with nested keys. - Option IDs:
<key type="post-ids" sub-type="page" name="...">or the relevant post type. - Shortcodes:
<shortcode-list>or<shortcodes>when translators must edit shortcode content/attributes.
Validate config values strictly: translate, display-as-translated, and
automatic are 0|1; custom-field action is exactly
translate|copy|copy-once|ignore.
Common findings
- High: user-facing shortcode/form output reads DB option strings but never
calls
wpml_translate_single_string. - High: stored
withdrawal_page_id, product ID, term ID, or attachment ID is used directly on translated pages. - High: e-mail/PDF generation ignores the language used when the case/order was submitted.
- Medium: no
wpml-config.xmlfor plugin options/meta/shortcodes. - Medium:
<admin-texts>exists, but the audit/test environment has WPML core without String Translation, so option-string behavior is not testable. - Medium: custom table has no language column even though rows are language-sensitive.
- Medium: JS editor strings use
@wordpress/i18nbut the script never callswp_set_script_translations(). - Low: admin-only labels are gettext-ready but no translation file exists.
Report format
Return:
- Verdict: Compatible / Partially compatible / Not compatible / Not testable.
- Environment: WPML core version, String Translation version/presence, WCML presence, plugin version, active competing multilingual plugins if relevant.
- Findings: severity, file/line, what breaks, and why.
- Fix plan: minimal code/config changes, grouped by string, ID/URL, query, shortcode/block, Woo, and async rendering.
- Residual risk: what still needs browser/WPML admin verification.
Cross-references
- Use
wpml-overviewfor the WPML copy/translation mental model. - Use
wpml-configwhen creating or validatingwpml-config.xml. - Use
wpml-string-translationfor dynamic option/admin-entered strings. - Use
wpml-language-apifor current language, object IDs, permalinks, and language switching. - Use
wp-i18n-auditfor core WordPress gettext and Loco/PO/MO issues.
References
Validated against WPML Multilingual CMS 4.9.5 and WPML String Translation 3.5.3 local source:
- API hook registration:
sitepress.class.php - Runtime callbacks:
inc/template-functions.php - Config parsing:
classes/xml-config/class-wpml-config.php - String hook call sites:
classes/language-switcher/class-wpml-ls-settings-strings.php - Explicit-language string translate example:
classes/url-handling/class-wpml-endpoints-support.php - Config schema:
res/xsd/wpml-config.xsd - String Translation bootstrap/version:
wpml-string-translation/plugin.php wpml_register_single_string/wpml_translate_single_stringhandlers:wpml-string-translation/inc/functions.php- Admin text config parsing and option filters:
wpml-string-translation/inc/private-actions.phpandwpml-string-translation/inc/admin-texts/wpml-admin-texts.class.php - Official documentation: https://wpml.org/documentation/support/wpml-coding-api/
- Official documentation: https://wpml.org/documentation/support/language-configuration-files/
- Official documentation: https://wpml.org/documentation/getting-started-guide/string-translation/
- Verified source paths:
wp-content/plugins/sitepress-multilingual-cms/sitepress.phpwp-content/plugins/wpml-string-translation/inc/admin-texts/wpml-admin-text-configuration.php
What ships with it: 1 file
217 B alongside SKILL.md
agents/
- openai.yaml217 B