הפילטר wptexturize של WordPress משבש בשקט JavaScript פנימי (inline), והופך את האופרטור הלוגי && לישות ה-HTML &&, מה ששובר סקריפטים שרצים בתוך שורטקודים (shortcodes).

הבעיה עלתה אצל מפתח האחראי על סט של שורטקודים למחשבונים. לאחר שבועות של פעולה ללא תקלות, כפתורי השליחה הפסיקו להגיב. לא היו אזהרות PHP, לא היו שגיאות בקונסולה, וה-HTML נראה תקין בבדיקה – עד שהמקור המרונדר (rendered source) חשף את if (!isNaN(bf) && bf > 0). שגיאת תחביר בודדת מנעה מכל בלוק הסקריפט להתבצע.

למה הפילטר הזה משנה

WordPress מעבד את תוכן הפוסט באמצעות סדרה של פילטרים לפני שהוא מגיע לדפדפן. wptexturize הוא הראשון שבהם; הוא הופך גרשיים ישרים לגרשיים טיפוגרפיים מעוגלים, מחליף מקפים כפולים בקו מפריד (em-dash), ומנקה אמפרסנדים (&). הפילטר מניח שהוא מתמודד עם טקסט ספרותי, לא עם קוד. כאשר שורטקוד מזריק תגית <script> פנימית, הפילטר עדיין רץ ומתייחס ל-JavaScript כטקסט רגיל. לכן, ה-ampersand ב-&& עובר escape ל-&#038;, מה שהדפדפן מפרש כמחרוזת טקסט ממשית ולא כאופרטור ה-AND הלוגי.

מפתחים שמשלבים JavaScript ישירות בתוכן הפוסט – מחשבונים, מאמתים טפסים, ווידג'טים אינטראקטיביים – חשופים לבעיה. הבעיה אינה מוגבלת למחשבונים; כל סקריפט פנימי המשתמש ב-&&, & או תווים דומים עלול להשתבש. מכיוון שהטרנספורמציה מתבצעת בצד השרת, הדפדפן לעולם לא רואה את הקוד המקורי, והשגיאה אינה מופיעה כחריגת JavaScript טיפוסית.

מי מושפע ומה הם מפסידים

  • בעלי אתרים: מחשבון או טופס שבור עלולים לתסכל מבקרים, להעלות את אחוז הנטישה ולערער את האמון.
  • מפתחים: שעות מבוזבזות על ציד באגים "רוחות רפאים" שלא משאירים עקבות בלוגים או בפלט הקונסולה.
  • עורכי תוכן: עלולים לשבור פונקציונליות מבלי לשים לב בעת עריכת דפים המכילים שורטקודים.

המחיר אינו רק זמן; הוא יכול לתרגם לאובדן המרות, במיוחד באתרים המסתמכים על מחשבונים מותאמים אישית לצורך תמחור, הערכות הלוואה או הערכות בריאותיות.

מה הפילטר עושה, במילים פשוטות

  1. מזהה גרשיים ישרים – מחליף את ' ו-" בגרסאות טיפוגרפיות "חכמות".
  2. מנקה אמפרסנדים – ממיר & ל-&amp; אלא אם הוא כבר מהווה ישות HTML תקפה.
  3. חל על מחרוזת התוכן כולה – כולל כל דבר בתוך תגיות <script> שנוצרות על ידי שורטקודים.

כאשר הפילטר נתקל ב-&&, הוא רואה שני אמפרסנדים שאינם חלק מישות HTML קיימת, ולכן הוא מבצע escape לכל אחד מהם בנפרד, מה שיוצר &#038;&#038;.

איך לעצור את השבירה

1. כבו את הפילטר עבור דפים המכילים קוד

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

קטע קוד זה מבטל את wptexturize רק בתבניות דפים (page templates), תוך שמירה על השיפורים הטיפוגרפיים עבור פוסטים וסוגי תוכן אחרים. הוא גם מסיר את הפילטר מטקסט של ווידג'טים, שיכול להיות מקור משני לסקריפטים פנימיים.

2. שכתבו את הלוגיקה כדי להימנע מ-&&

אם הסרת הפילטר אינה רצויה, בצעו רפקטורינג (refactor) ל-JavaScript כך שלא יהיה צורך באופרטור ה-AND הלוגי:

הפשרה היא השבתה סלקטיבית: כבו את המסנן רק במקומות שבהם נמצא קוד, או השתמשו ב-shortcode מותאם אישית שמסמן במפורש את הפלט שלו כבטוח מפני texturizing. WordPress כבר מספקת את wp_kses_post ועזרי sanitisation נוספים; מפתחים יכולים לשלב אותם עם קריאות ל-remove_filter כדי ליהנות משני העולמות.

מה כדאי לעקוב אחריו בהמשך

ליבת WordPress טרם הודיעה על שינוי ב-wptexturize שיפטור באופן אוטומטי תגיות <script>. עד ששינוי כזה יתבצע, מפתחים חייבים להגן על הקוד ה-inline שלהם באופן ידני. עקבו אחר ה-core development tracker לכל הצעה להפוך את המסנן ל-context-aware. בינתיים, בצעו audit לכל shortcode או אלמנט של page builder שמזריק JavaScript ויישמו את אחד משלושת התיקונים לעיל.

בשורה התחתונה: אם אתר ה-WordPress שלכם מריץ JavaScript inline, ודאו ש-wptexturize לא כותב אותו מחדש בשקט. ampersand אחד שעבר escaping יכול להפוך פיצ'ר שלם לחסר תועלת, והתיקון הוא בדרך כלל כמה שורות PHP או מעבר לסקריפטים חיצוניים.