Filtr wptexturize w WordPressie po cichu uszkadza wstawiany w linii JavaScript, zamieniając logiczny operator && na encję HTML &&, co powoduje błędy w skryptach działających wewnątrz shortcode'ów.

Problem pojawił się u programisty utrzymującego zestaw shortcode'ów kalkulatorów. Po tygodniach bezbłędnego działania przyciski wysyłania przestały reagować. Brak ostrzeżeń PHP, brak błędów w konsoli, a sprawdzony kod HTML wyglądał czysto – dopóki wyrenderowane źródło nie ujawniło if (!isNaN(bf) && bf > 0). Ten pojedynczy błąd składni uniemożliwił wykonanie całego bloku skryptu.

Dlaczego ten filtr jest istotny

WordPress przetwarza treść wpisów przez szereg filtrów, zanim trafi ona do przeglądarki. wptexturize jest pierwszym z nich; zamienia proste cudzysłowy na typograficzne cudzysłowy krzywe, zastępuje wielokrotne myślniki pauzami (em-dash) i oczyszcza ampersandy. Filtr zakłada, że pracuje z prozą, a nie z kodem. Gdy shortcode wstawia w linii znacznik <script>, filtr nadal działa, traktując JavaScript jako zwykły tekst. W rezultacie ampersand w && zostaje zamieniony na &#038;, co przeglądarka interpretuje jako dosłowny ciąg znaków, a nie logiczny operator AND.

Programiści, którzy osadzają jakikolwiek JavaScript bezpośrednio w treści wpisów – kalkulatory, walidatory formularzy, interaktywne widgety – są narażeni na ten problem. Kwestia ta nie ogranicza się tylko do kalkulatorów; każdy skrypt wstawiony w linii, który używa &&, & lub podobnych znaków, może zostać uszkodzony. Ponieważ transformacja odbywa się po stronie serwera, przeglądarka nigdy nie widzi oryginalnego kodu, a błąd nie objawia się jako typowy wyjątek JavaScript.

Kogo to dotyczy i co tracą

  • Właściciele stron: niedziałający kalkulator lub formularz może frustrować odwiedzających, zwiększać współczynnik odrzuceń i obniżać zaufanie.
  • Programiści: godziny spędzone na tropieniu „duchów” (ghost bugs), które nie zostawiają śladu w logach ani w konsoli.
  • Redaktorzy treści: mogą nieświadomie uszkodzić funkcjonalność podczas edycji stron zawierających shortcode'y.

Kosztem nie jest tylko czas; może to oznaczać utratę konwersji, szczególnie na stronach polegających na niestandardowych kalkulatorach do wyceny, szacowania kredytów czy ocen zdrowotnych.

Co robi ten filtr (mówiąc prościej)

  1. Wykrywa proste cudzysłowy – zastępuje ' oraz " ich „inteligentnymi” wersjami typograficznymi.
  2. Oczyszcza ampersandy – zamienia & na &amp;, chyba że tworzy on już poprawną encję HTML.
  3. Stosuje się do całego ciągu treści – w tym do wszystkiego, co znajduje się wewnątrz znaczników <script> generowanych przez shortcode'y.

Gdy filtr napotka &&, widzi dwa ampersandy, które nie są częścią istniejącej encji HTML, więc ucieka każdy z nich z osobna, co skutkuje &#038;&#038;.

Jak zapobiec uszkodzeniu kodu

1. Wyłącz filtr dla stron zawierających kod

add_action( 'template_redirect', function () {
    if ( is_page() ) {
        remove_filter( 'the_content', 'wptexturize' );
        remove_filter( 'widget_text_content', 'wptexturize' );
    }
} );

Ten fragment kodu wyłącza wptexturize tylko w szablonach stron, zachowując ulepszenia typograficzne dla wpisów i innych typów treści. Usuwa on również filtr z tekstu widgetów, które mogą być wtórnym źródłem skryptów w linii.

2. Przepisz logikę, aby uniknąć &&

Jeśli usunięcie filtra nie jest pożądane, przeprowadź refaktoryzację JavaScriptu tak, aby nie był potrzebny operator logiczny AND:

// Original
if (a && b) { … }

// Refactored
var ok = a;
if (ok) { ok = b; }
if (ok) { … }

Choć dodaje to kilka dodatkowych linii, eliminuje ampersand wyzwalający filtr. Podejście to sprawdza się przy prostych warunkach, ale może stać się nieporęczne przy złożonych wyrażeniach.

3. Przenieś wszystkie skrypty do zewnętrznych plików

Najbardziej niezawodnym rozwiązaniem jest kolejkowanie (enqueue) plików JavaScript zamiast osadzania kodu w linii:

wp_enqueue_script( 'my-calculator', get_template_directory_uri() . '/js/calculator.js', [], null, true );

Skrypty dodane przez kolejkę całkowicie omijają filtry the_content. Korzystają one również z buforowania przez przeglądarkę i mogą być minifikowane lub łączone z innymi zasobami.

Jak wykryć problem w działającym serwisie

Gdy skrypt przestaje działać bez wyraźnych błędów, wyświetl źródło strony (nie inspektor DOM) i wyszukaj &#038;. Jeśli znajdziesz go wewnątrz bloku <script>, winowajcą jest filtr. Problem nie pojawi się w konsoli, ponieważ przeglądarka nigdy nie otrzyma syntaktycznie poprawnego skryptu do przetworzenia.

Kontrargument: dlaczego warto zostawić wptexturize?

wptexturize poprawia czytelność na froncie. Cudzysłowy krzywe i właściwe znaki myślników nadają prozie dopracowany wygląd, a wielu właścicieli stron uważa to za niepodlegającą negocjacjom cechę estetyczną. Globalne usunięcie filtra przywróciłoby tekst do jego surowego, typograficznie płaskiego stanu.

Kompromisem jest selektywne wyłączanie: wyłącz filtr tylko tam, gdzie znajduje się kod, lub użyj niestandardowego shortcode'u, który wyraźnie oznacza jego wyjście jako bezpieczne przed teksturyzacją. WordPress oferuje już wp_kses_post i inne funkcje pomocnicze do sanityzacji; programiści mogą łączyć je z wywołaniami remove_filter, aby zachować to, co najlepsze z obu rozwiązań.

Na co zwrócić uwagę w przyszłości

Rdzeń WordPress nie ogłosił zmiany w wptexturize, która automatycznie wyłączałaby tagi <script>. Do czasu wprowadzenia takiej zmiany programiści muszą ręcznie zabezpieczać swój kod inline. Należy śledzić tracker rozwoju rdzenia pod kątem wszelkich propozycji uczynienia filtra świadomym kontekstu. W międzyczasie należy przeprowadzić audyt każdego shortcode'u lub elementu page buildera, który wstrzykuje JavaScript, i zastosować jedną z trzech powyższych poprawek.

Podsumowując: jeśli Twoja strona WordPress uruchamia inline JavaScript, upewnij się, że wptexturize po cichu go nie przepisuje. Pojedynczy zakodowany znak ampersanda może sprawić, że cała funkcja przestanie działać, a rozwiązaniem jest zazwyczaj kilka linii PHP lub przejście na zewnętrzne skrypty.