يقوم مرشح wptexturize في WordPress بتشويه جافا سكريبت المضمن (inline JavaScript) بصمت، حيث يحول عامل المنطق && إلى كيان HTML **&&**، مما يؤدي إلى تعطل البرامج النصية التي تعمل داخل الأكواد القصيرة (shortcodes).
ظهرت المشكلة لمطور يقوم بصيانة مجموعة من الأكواد القصيرة (shortcodes) الخاصة بالآلات الحاسبة. فبعد أسابيع من العمل دون أي مشاكل، توقفت أزرار الإرسال عن الاستجابة. لم تظهر أي تحذيرات PHP، ولا أخطاء في وحدة التحكم (console)، وبدا كود HTML نظيفاً عند فحصه — حتى كشف المصدر المُعالج عن if (!isNaN(bf) && bf > 0). وقد منع هذا الخطأ النحوي الوحيد كتلة البرمجية النصية بأكملها من التنفيذ.
لماذا يهم هذا المرشح
يعالج WordPress محتوى المنشورات عبر سلسلة من المرشحات (filters) قبل وصولها إلى المتصفح. ويُعد wptexturize أول هذه المرشحات؛ حيث يقوم بتحويل علامات الاقتباس المستقيمة إلى علامات اقتباس منحنية طباعية، ويستبدل الشرطات المتعددة بشرطات طويلة (em-dashes)، وينظف علامات الـ ampersand (&). يفترض المرشح أنه يتعامل مع نص أدبي وليس مع كود برمجي. وعندما يقوم كود قصير (shortcode) بحقن وسم <script> مضمن، يستمر المرشح في العمل، معاملاً الجافا سكريبت كنص عادي. وبالتالي يتم تحويل علامة الـ ampersand في && إلى & ، والتي يفسرها المتصفح كنص حرفي بدلاً من عامل المنطق AND.
المطورون الذين يضمنون أي جافا سكريبت مباشرة في محتوى المنشور — مثل الآلات الحاسبة، أو أدوات التحقق من النماذج، أو الأدوات التفاعلية — معرضون لهذه المشكلة. ولا تقتصر المشكلة على الآلات الحاسبة فحسب؛ بل إن أي نص برمجي مضمن يستخدم && أو & أو رموزاً مماثلة يمكن أن يتعرض للتلف. ولأن عملية التحويل تحدث في جانب الخادم (server-side)، فإن المتصفح لا يرى الكود الأصلي أبداً، ولا يظهر الخطأ كاستثناء جافا سكريبت (JavaScript exception) تقليدي.
من يتأثر وماذا يخسرون
- أصحاب المواقع: يمكن للآلة الحاسبة أو النموذج المعطل أن يثير إحباط الزوار، ويزيد من معدلات الارتداد (bounce rates)، ويقوض الثقة.
- المطورون: قضاء ساعات في مطاردة أخطاء "شبحية" لا تترك أي أثر في السجلات (logs) أو مخرجات وحدة التحكم (console).
- محررو المحتوى: قد يتسببون دون قصد في تعطيل الوظائف أثناء تحرير الصفحات التي تحتوي على أكواد قصيرة (shortcodes).
التكلفة ليست مجرد وقت؛ بل يمكن أن تترجم إلى فقدان عمليات التحويل (conversions)، خاصة في المواقع التي تعتمد على آلات حاسبة مخصصة لتسعير الخدمات، أو تقديرات القروض، أو التقييمات الصحية.
ما يفعله المرشح، بعبارات بسيطة
- يكتشف علامات الاقتباس المستقيمة – يستبدل
'و"بنسخ طباعية "ذكية". - ينظف علامات الـ ampersand – يحول
&إلى&ما لم تكن تشكل بالفعل كيان HTML صالحاً. - ينطبق على سلسلة المحتوى بأكملها – بما في ذلك أي شيء داخل وسوم
<script>التي يتم إنشاؤها بواسطة الأكواد القصيرة (shortcodes).
عندما يواجه المرشح && فإنه يرى علامتي ampersand ليستا جزءاً من كيان HTML موجود، لذا يقوم بتحويل كل واحدة منهما على حدة، مما ينتج عنه &&.
كيف توقف هذا التشويه
1. إيقاف تشغيل المرشح للصفحات التي تحتوي على كود
add_action( 'template_redirect', function () {
if ( is_page() ) {
remove_filter( 'the_content', 'wptexturize' );
remove_filter( 'widget_text_content', 'wptexturize' );
}
} );
يقوم هذا المقتطف بتعطيل wptexturize فقط في قوالب الصفحات، مع الحفاظ على التحسينات الطباعية للمنشورات وأنواع المحتوى الأخرى. كما أنه يزيل المرشح من نص الودجت (widget text)، والذي يمكن أن يكون مصدراً ثانوياً للنصوص البرمجية المضمنة.
2. إعادة كتابة المنطق لتجنب &&
إذا لم يكن إزالة المرشح خياراً مرغوباً فيه، فقم بإعادة صياغة (refactor) الجافا سكريبت بحيث لا تكون هناك حاجة لعامل المنطق AND:
// Original
if (a && b) { … }
// Refactored
var ok = a;
if (ok) { ok = b; }
if (ok) { … }
على الرغم من أن هذا يضيف بضعة أسطر إضافية، إلا أنه يزيل علامة الـ ampersand التي تفعّل المرشح. يعمل هذا النهج مع الشروط البسيطة ولكنه قد يصبح معقداً في التعبيرات المعقدة.
3. جعل جميع النصوص البرمجية خارجية
الحل الأكثر قوة هو استخدام enqueue لملفات الجافا سكريبت بدلاً من تضمين الكود مباشرة:
wp_enqueue_script( 'my-calculator', get_template_directory_uri() . '/js/calculator.js', [], null, true );
تتجاوز النصوص البرمجية التي يتم إدراجها عبر enqueue مرشحات the_content تماماً. كما أنها تستفيد من ذاكرة التخزين المؤقت للمتصفح ويمكن تصغير حجمها (minified) أو دمجها مع أصول أخرى.
اكتشاف المشكلة في الواقع
عندما يتوقف نص برمجي عن العمل دون أخطاء واضحة، قم بعرض مصدر الصفحة (وليس فاحص DOM) وابحث عن &. إذا وجدته داخل كتلة <script>، فإن المرشح هو المسبب. لن تظهر المشكلة في وحدة التحكم لأن المتصفح لا يتلقى أبداً نصاً برمجياً صالحاً من الناحية النحوية ليقوم بتحليله.
وجهة نظر أخرى: لماذا نحتفظ بـ wptexturize؟
يحسن wptexturize من سهولة القراءة في الواجهة الأمامية (front end). تمنح علامات الاقتباس المنحنية ورموز الشرطات الصحيحة النص مظهراً مصقولاً، ويعتبر العديد من أصحاب المواقع أن ذلك ميزة جمالية لا يمكن التنازل عنها. إن إزالة المرشح بشكل شامل سيعيد النص إلى حالته الخام والبسيطة من الناحية الطباعية.
الحل الوسط هو التعطيل الانتقائي: إيقاف تشغيل الفلتر فقط في الأماكن التي يتواجد فيها الكود، أو استخدام كود قصير (shortcode) مخصص يحدد بوضوح أن مخرجاته آمنة من عملية الـ texturizing. يوفر WordPress بالفعل wp_kses_post وأدوات مساعدة أخرى للتنقية (sanitisation)؛ ويمكن للمطورين الجمع بين هذه الأدوات واستدعاءات remove_filter للحصول على أفضل ما في الأمرين.
ما يجب مراقبته لاحقاً
لم يعلن نواة WordPress عن أي تغيير في wptexturize من شأنه استثناء وسوم <script> تلقائياً. وإلى حين حدوث مثل هذا التغيير، يجب على المطورين حماية الكود المضمن (inline code) يدوياً. تابع متتبع تطوير النواة (core development tracker) بحثاً عن أي مقترحات لجعل الفلتر مدركاً للسياق (context-aware). وفي هذه الأثناء، قم بمراجعة أي كود قصير (shortcode) أو عنصر في أدوات بناء الصفحات (page builder) يقوم بحقن JavaScript وطبق أحد الإصلاحات الثلاثة المذكورة أعلاه.
الخلاصة: إذا كان موقع WordPress الخاص بك يشغل JavaScript مضمناً، فتأكد من أن wptexturize لا يعيد كتابته بصمت. فمجرد علامة ampersand واحدة مُعالجَة (escaped) قد تؤدي إلى تعطيل ميزة كاملة، وعادة ما يكون الإصلاح عبارة عن بضعة أسطر من PHP أو الانتقال إلى استخدام سكربتات خارجية.
