Policy
WordPress.org-supplied translations are trusted. The translation string itself does not need to be escaped — only data interpolated into it.
What this means in practice
- Replace
esc_html__() / esc_html_e() / esc_attr__() / esc_attr_e() with __() / _e() / _x() / _ex() for the static, translator-provided portion of strings.
- Continue to escape interpolated values: variables, IDs, URLs, user content, etc. should still go through
esc_html(), esc_attr(), esc_url(), esc_js(), etc. before being placed into output.
- In
printf() / sprintf() patterns, escape the substituted values, not the format string.
Before
wp_die(
esc_html__( 'This invite link is invalid or has been revoked.', 'multi-author-posts' ),
esc_html__( 'Invalid Invite', 'multi-author-posts' ),
array( 'response' => 403 )
);
After
wp_die(
__( 'This invite link is invalid or has been revoked.', 'multi-author-posts' ),
__( 'Invalid Invite', 'multi-author-posts' ),
array( 'response' => 403 )
);
Rationale
- WordPress.org Polyglots translations go through review and are trusted not to inject markup.
- Double-escaping the static string adds noise and can corrupt characters (entities, smart quotes) inside the translated copy.
- The actual XSS risk is in interpolated data, which we keep escaping.
Scope
includes/class-map-invite.php has the two esc_html__() calls inside the wp_die() invalid-invite branch. No other files use the escaping wrappers today.
Plugin Check currently flags the un-escaped form as WordPress.Security.EscapeOutput.UnsafePrintingFunction / OutputNotEscaped; those codes are downgraded to warnings in .github/workflows/plugin-check.yml per this policy.
Out of scope
- Strings concatenated with untrusted markup that must be escaped as a whole — keep wrapping the whole composite through
wp_kses_* if needed.
- HTML attribute contexts where the translation is the entire attribute value — case-by-case; escaping the variable being inserted is usually enough.
Policy
WordPress.org-supplied translations are trusted. The translation string itself does not need to be escaped — only data interpolated into it.
What this means in practice
esc_html__()/esc_html_e()/esc_attr__()/esc_attr_e()with__()/_e()/_x()/_ex()for the static, translator-provided portion of strings.esc_html(),esc_attr(),esc_url(),esc_js(), etc. before being placed into output.printf()/sprintf()patterns, escape the substituted values, not the format string.Before
After
Rationale
Scope
includes/class-map-invite.phphas the twoesc_html__()calls inside thewp_die()invalid-invite branch. No other files use the escaping wrappers today.Plugin Check currently flags the un-escaped form as
WordPress.Security.EscapeOutput.UnsafePrintingFunction/OutputNotEscaped; those codes are downgraded to warnings in.github/workflows/plugin-check.ymlper this policy.Out of scope
wp_kses_*if needed.