WordPress’s wptexturize filter is silently mangling inline JavaScript, turning the logical && operator into the HTML entity && and breaking scripts that run inside shortcodes.
The problem surfaced for a developer who maintains a set of calculator shortcodes. After weeks of flawless operation, the submit buttons stopped responding. No PHP warnings, no console errors, and the HTML inspected clean—until the rendered source revealed if (!isNaN(bf) && bf > 0). The single syntax error prevented the entire script block from executing.
Why the filter matters
WordPress processes post content through a series of filters before it reaches the browser. wptexturize is the first of those filters; it converts straight quotes to typographic curly quotes, replaces multiple hyphens with em-dashes, and sanitises ampersands. The filter assumes it is dealing with prose, not code. When a shortcode injects an inline <script> tag, the filter still runs, treating the JavaScript as ordinary text. The ampersand in && is therefore escaped to &, which the browser interprets as a literal string rather than the logical AND operator.
Developers who embed any JavaScript directly in post content—calculators, form validators, interactive widgets—are vulnerable. The issue is not limited to calculators; any inline script that uses &&, &, or similar characters can be corrupted. Because the transformation happens server-side, the browser never sees the original code, and the error does not surface as a typical JavaScript exception.
Who is affected and what they lose
- Site owners: a broken calculator or form can frustrate visitors, increase bounce rates, and erode trust.
- Developers: hours spent hunting “ghost” bugs that leave no trace in logs or console output.
- Content editors: may unknowingly break functionality while editing pages that contain shortcodes.
The cost is not just time; it can translate into lost conversions, especially on sites that rely on custom calculators for pricing, loan estimates, or health assessments.
What the filter does, in plain terms
- Detects straight quotes – replaces
'and"with ‘smart’ typographic versions. - Cleans ampersands – converts
&to&unless it already forms a valid HTML entity. - Applies to the entire content string – including anything inside
<script>tags that are generated by shortcodes.
When the filter encounters &&, it sees two ampersands that are not part of an existing HTML entity, so it escapes each one individually, resulting in &&.
How to stop the corruption
1. Turn off the filter for pages that contain code
add_action( 'template_redirect', function () {
if ( is_page() ) {
remove_filter( 'the_content', 'wptexturize' );
remove_filter( 'widget_text_content', 'wptexturize' );
}
} );
This snippet disables wptexturize only on page templates, preserving the typographic improvements for posts and other content types. It also removes the filter from widget text, which can be a secondary source of inline scripts.
2. Rewrite logic to avoid &&
If removing the filter is not desirable, refactor the JavaScript so that the logical AND operator is not needed:
// Original
if (a && b) { … }
// Refactored
var ok = a;
if (ok) { ok = b; }
if (ok) { … }
While this adds a few extra lines, it eliminates the ampersand that triggers the filter. The approach works for simple conditions but can become unwieldy for complex expressions.
3. Externalise all scripts
The most robust solution is to enqueue JavaScript files instead of embedding code inline:
wp_enqueue_script( 'my-calculator', get_template_directory_uri() . '/js/calculator.js', [], null, true );
Enqueued scripts bypass the_content filters entirely. They also benefit from browser caching and can be minified or bundled with other assets.
Detecting the issue in the wild
When a script stops running without obvious errors, view the page source (not the DOM inspector) and search for &. If you find it inside a <script> block, the filter is the culprit. The problem will not appear in the console because the browser never receives a syntactically valid script to parse.
Counterpoint: why keep wptexturize?
wptexturize improves readability on the front end. Curly quotes and proper dash characters give prose a polished look, and many site owners consider that a non-negotiable aesthetic feature. Removing the filter globally would revert text to its raw, typographically plain state.
Il compromesso consiste nella disattivazione selettiva: disattiva il filtro solo dove risiede il codice, oppure utilizza uno shortcode personalizzato che segni esplicitamente il proprio output come sicuro dalla texturizzazione. WordPress fornisce già wp_kses_post e altri helper di sanificazione; gli sviluppatori possono combinarli con chiamate a remove_filter per ottenere il meglio dai due mondi.
Cosa tenere d'occhio
Il core di WordPress non ha annunciato modifiche a wptexturize che esentino automaticamente i tag <script>. Fino a quando non verrà implementata una modifica del genere, gli sviluppatori dovranno proteggere manualmente il proprio codice inline. Tieni d'occhio il tracker dello sviluppo del core per eventuali proposte volte a rendere il filtro consapevole del contesto. Nel frattempo, esamina qualsiasi shortcode o elemento di page builder che inietti JavaScript e applica una delle tre soluzioni sopra descritte.
In sintesi: se il tuo sito WordPress esegue JavaScript inline, verifica che wptexturize non lo stia riscrivendo silenziosamente. Un singolo ampersand escapato può rendere inerte un'intera funzionalità, e la soluzione consiste solitamente in poche righe di PHP o nel passaggio a script esterni.
