O filtro wptexturize do WordPress está corrompendo silenciosamente o JavaScript inline, transformando o operador lógico && na entidade HTML && e quebrando scripts que rodam dentro de shortcodes.
O problema surgiu para um desenvolvedor que mantém um conjunto de shortcodes de calculadora. Após semanas de operação impecável, os botões de envio pararam de responder. Sem avisos de PHP, sem erros de console e com o HTML inspecionado parecendo limpo — até que o código-fonte renderizado revelou if (!isNaN(bf) && bf > 0). O único erro de sintaxe impediu a execução de todo o bloco de script.
Por que o filtro é importante
O WordPress processa o conteúdo dos posts por meio de uma série de filtros antes de chegar ao navegador. O wptexturize é o primeiro desses filtros; ele converte aspas retas em aspas tipográficas curvas, substitui múltiplos hifens por travessões (em-dashes) e higieniza os e-comerciais (&). O filtro assume que está lidando com prosa, não com código. Quando um shortcode injeta uma tag <script> inline, o filtro ainda é executado, tratando o JavaScript como texto comum. O e-comercial em && é, portanto, escapado para &, que o navegador interpreta como uma string literal em vez do operador lógico AND.
Desenvolvedores que incorporam qualquer JavaScript diretamente no conteúdo do post — calculadoras, validadores de formulários, widgets interativos — estão vulneráveis. O problema não se limita a calculadoras; qualquer script inline que use &&, & ou caracteres semelhantes pode ser corrompido. Como a transformação ocorre no lado do servidor, o navegador nunca vê o código original, e o erro não aparece como uma exceção típica de JavaScript.
Quem é afetado e o que perdem
- Proprietários de sites: uma calculadora ou formulário quebrado pode frustrar os visitantes, aumentar as taxas de rejeição e corroer a confiança.
- Desenvolvedores: horas gastas caçando bugs "fantasmas" que não deixam rastros nos logs ou na saída do console.
- Editores de conteúdo: podem quebrar funcionalidades sem saber ao editar páginas que contêm shortcodes.
O custo não é apenas tempo; pode se traduzir em perda de conversões, especialmente em sites que dependem de calculadoras personalizadas para precificação, estimativas de empréstimos ou avaliações de saúde.
O que o filtro faz, em termos simples
- Detecta aspas retas – substitui
'e"por versões tipográficas "inteligentes". - Limpa e-comerciais – converte
¶&, a menos que já forme uma entidade HTML válida. - Aplica-se a toda a string de conteúdo – incluindo qualquer coisa dentro de tags
<script>que sejam geradas por shortcodes.
Quando o filtro encontra &&, ele vê dois e-comerciais que não fazem parte de uma entidade HTML existente, então escapa cada um individualmente, resultando em &&.
Como interromper a corrupção
1. Desative o filtro para páginas que contêm código
add_action( 'template_redirect', function () {
if ( is_page() ) {
remove_filter( 'the_content', 'wptexturize' );
remove_filter( 'widget_text_content', 'wptexturize' );
}
} );
Este trecho desativa o wptexturize apenas em templates de página, preservando as melhorias tipográficas para posts e outros tipos de conteúdo. Ele também remove o filtro do texto de widgets, que pode ser uma fonte secundária de scripts inline.
2. Reescreva a lógica para evitar &&
Se a remoção do filtro não for desejável, refatore o JavaScript para que o operador lógico AND não seja necessário:
// Original
if (a && b) { … }
// Refactored
var ok = a;
if (ok) { ok = b; }
if (ok) { … }
Embora isso adicione algumas linhas extras, elimina o e-comercial que aciona o filtro. A abordagem funciona para condições simples, mas pode se tornar complexa para expressões elaboradas.
3. Externalize todos os scripts
A solução mais robusta é enfileirar arquivos JavaScript em vez de incorporar o código inline:
wp_enqueue_script( 'my-calculator', get_template_directory_uri() . '/js/calculator.js', [], null, true );
Scripts enfileirados ignoram completamente os filtros de the_content. Eles também se beneficiam do cache do navegador e podem ser minificados ou agrupados com outros recursos.
Detectando o problema na prática
Quando um script para de funcionar sem erros óbvios, visualize o código-fonte da página (não o inspetor do DOM) e procure por &. Se você encontrá-lo dentro de um bloco <script>, o filtro é o culpado. O problema não aparecerá no console porque o navegador nunca recebe um script sintaticamente válido para analisar.
Contraponto: por que manter o wptexturize?
O wptexturize melhora a legibilidade no front end. Aspas curvas e caracteres de travessão adequados dão à prosa um visual polido, e muitos proprietários de sites consideram isso um recurso estético inegociável. Remover o filtro globalmente faria o texto retornar ao seu estado bruto e tipograficamente simples.
The compromise is selective disabling: turn the filter off only where code lives, or use a custom shortcode that explicitly marks its output as safe from texturizing. WordPress already provides wp_kses_post and other sanitisation helpers; developers can combine those with remove_filter calls to keep the best of both worlds.
What to watch next
WordPress core has not announced a change to wptexturize that would automatically exempt <script> tags. Until such a change lands, developers must guard their inline code manually. Keep an eye on the core development tracker for any proposals to make the filter context-aware. In the meantime, audit any shortcode or page builder element that injects JavaScript and apply one of the three fixes above.
Bottom line: if your WordPress site runs inline JavaScript, verify that wptexturize isn’t silently rewriting it. A single escaped ampersand can render an entire feature inert, and the fix is usually a few lines of PHP or a shift to external scripts.
