WordPress-এর wptexturize ফিল্টারটি নিঃশব্দে ইনলাইন JavaScript নষ্ট করে দিচ্ছে, যেখানে লজিক্যাল && অপারেটরটি HTML এনটিটি &&-এ রূপান্তরিত হচ্ছে এবং শর্টকোডের (shortcodes) ভেতরে চলা স্ক্রিপ্টগুলোকে অকেজো করে দিচ্ছে।

সমস্যাটি একজন ডেভেলপারের ক্ষেত্রে দেখা দেয় যিনি ক্যালকুলেটর শর্টকোডের একটি সেট রক্ষণাবেক্ষণ করেন। কয়েক সপ্তাহ নিখুঁতভাবে চলার পর, সাবমিট বাটনগুলো কাজ করা বন্ধ করে দেয়। কোনো PHP ওয়ার্নিং বা কনসোল এরর ছিল না, এমনকি HTML ইন্সপেক্ট করলেও সবকিছু ঠিকঠাক দেখাচ্ছিল—যতক্ষণ না রেন্ডার করা সোর্স কোডে if (!isNaN(bf) && bf > 0) দেখা গেল। এই একটি মাত্র সিনট্যাক্স এরর পুরো স্ক্রিপ্ট ব্লকটি কার্যকর হতে বাধা দিচ্ছিল।

কেন এই ফিল্টারটি গুরুত্বপূর্ণ

ব্রাউজারে পৌঁছানোর আগে WordPress পোস্টের কন্টেন্টকে কতগুলো ফিল্টারের মাধ্যমে প্রসেস করে। wptexturize হলো সেই ফিল্টারগুলোর মধ্যে প্রথম; এটি সোজা কোটেশন মার্কগুলোকে টাইপোগ্রাফিক কার্লি কোটেশনে (curly quotes) রূপান্তর করে, একাধিক হাইফেনকে এম-ড্যাশ (em-dashes) দিয়ে প্রতিস্থাপন করে এবং অ্যাম্পারস্যান্ড (&) স্যানিটাইজ করে। ফিল্টারটি ধরে নেয় যে এটি সাধারণ গদ্য (prose) নিয়ে কাজ করছে, কোড নয়। যখন একটি শর্টকোড ইনলাইন <script> ট্যাগ ইনজেক্ট করে, ফিল্টারটি তখনও কাজ করে এবং JavaScript-কে সাধারণ টেক্সট হিসেবে বিবেচনা করে। ফলে &&-এর অ্যাম্পারস্যান্ডটি &#038;-এ রূপান্তরিত হয়, যা ব্রাউজার লজিক্যাল AND অপারেটর হিসেবে না দেখে একটি সাধারণ স্ট্রিং হিসেবে ব্যাখ্যা করে।

যেসব ডেভেলপার পোস্ট কন্টেন্টের ভেতরে সরাসরি কোনো JavaScript যুক্ত করেন—যেমন ক্যালকুলেটর, ফর্ম ভ্যালিডেটর বা ইন্টারেক্টিভ উইজেট—তারা এই সমস্যার সম্মুখীন হতে পারেন। এই সমস্যাটি শুধু ক্যালকুলেটরের মধ্যেই সীমাবদ্ধ নয়; যে কোনো ইনলাইন স্ক্রিপ্ট যা &&, & বা এই জাতীয় ক্যারেক্টার ব্যবহার করে, তা ক্ষতিগ্রস্ত হতে পারে। যেহেতু এই রূপান্তরটি সার্ভার-সাইডে ঘটে, তাই ব্রাউজার কখনোই আসল কোডটি দেখতে পায় না এবং এই এররটি সাধারণ JavaScript exception হিসেবে প্রকাশ পায় না।

কারা ক্ষতিগ্রস্ত হচ্ছে এবং তাদের কী ক্ষতি হয়

  • সাইট মালিক: একটি ত্রুটিপূর্ণ ক্যালকুলেটর বা ফর্ম ভিজিটরদের বিরক্ত করতে পারে, বাউন্স রেট বাড়িয়ে দিতে পারে এবং বিশ্বাসযোগ্যতা কমিয়ে দিতে পারে।
  • ডেভেলপার: লগ বা কনসোল আউটপুটে কোনো চিহ্ন না রাখা “ghost” বাগ খুঁজে বের করতে ঘণ্টার পর ঘণ্টা সময় নষ্ট হয়।
  • কন্টেন্ট এডিটর: শর্টকোড সম্বলিত পেজ এডিট করার সময় অজান্তেই কার্যকারিতা নষ্ট করে ফেলতে পারেন।

এর ক্ষতি শুধু সময়ের নয়; এটি কনভার্সন হারিয়ে ফেলার কারণ হতে পারে, বিশেষ করে সেইসব সাইটের ক্ষেত্রে যা প্রাইসিং, লোনের হিসাব বা স্বাস্থ্য বিষয়ক মূল্যায়নের জন্য কাস্টম ক্যালকুলেটরের ওপর নির্ভর করে।

সহজ কথায় ফিল্টারটি কী করে

  1. সোজা কোটেশন শনাক্ত করে' এবং " কে ‘স্মার্ট’ টাইপোগ্রাফিক ভার্সন দিয়ে প্রতিস্থাপন করে।
  2. অ্যাম্পারস্যান্ড পরিষ্কার করে& কে &amp;-এ রূপান্তর করে, যদি না এটি আগে থেকেই একটি বৈধ HTML এনটিটি হয়।
  3. পুরো কন্টেন্ট স্ট্রিংয়ের ওপর প্রয়োগ হয় – শর্টকোড দ্বারা তৈরি <script> ট্যাগের ভেতরের বিষয়সহ সবকিছুর ওপর।

যখন ফিল্টারটি && পায়, তখন এটি দেখে যে এখানে দুটি অ্যাম্পারস্যান্ড আছে যা কোনো বিদ্যমান HTML এনটিটির অংশ নয়, তাই এটি প্রতিটি অ্যাম্পারস্যান্ডকে আলাদাভাবে এস্কেপ করে, যার ফলে &#038;&#038; তৈরি হয়।

কীভাবে এই সমস্যা সমাধান করবেন

১. কোড সম্বলিত পেজগুলোর জন্য ফিল্টারটি বন্ধ করুন

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

এই স্নিপেটটি শুধুমাত্র পেজ টেমপ্লেটগুলোতে wptexturize নিষ্ক্রিয় করে, ফলে পোস্ট এবং অন্যান্য কন্টেন্ট টাইপের জন্য টাইপোগ্রাফিক উন্নতিগুলো বজায় থাকে। এটি উইজেট টেক্সট থেকেও ফিল্টারটি সরিয়ে দেয়, যা ইনলাইন স্ক্রিপ্টের একটি গৌণ উৎস হতে পারে।

২. && এড়াতে লজিক পুনরায় লিখুন

যদি ফিল্টারটি সরিয়ে ফেলা কাম্য না হয়, তবে JavaScript রিফ্যাক্টর করুন যাতে লজিক্যাল AND অপারেটরের প্রয়োজন না হয়:

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

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

যদিও এতে কয়েক লাইন কোড বেড়ে যায়, তবে এটি সেই অ্যাম্পারস্যান্ডটি সরিয়ে ফেলে যা ফিল্টারটিকে ট্রিগার করে। এই পদ্ধতিটি সাধারণ শর্তের ক্ষেত্রে কাজ করে কিন্তু জটিল এক্সপ্রেশনের ক্ষেত্রে কিছুটা জটিল হয়ে উঠতে পারে।

৩. সব স্ক্রিপ্ট এক্সটার্নাল করুন

সবচেয়ে কার্যকর সমাধান হলো কোড ইনলাইন করার পরিবর্তে JavaScript ফাইলগুলো enqueue করা:

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

Enqueued স্ক্রিপ্টগুলো the_content ফিল্টারগুলোকে সম্পূর্ণ এড়িয়ে চলে। এগুলো ব্রাউজার ক্যাশিংয়ের সুবিধাও পায় এবং চাইলে মিনিফাই (minify) বা অন্যান্য অ্যাসেটের সাথে বান্ডেল করা যায়।

সমস্যাটি কীভাবে শনাক্ত করবেন

যখন কোনো স্ক্রিপ্ট কোনো স্পষ্ট এরর ছাড়াই কাজ করা বন্ধ করে দেয়, তখন পেজ সোর্স (DOM ইন্সপেক্টর নয়) দেখুন এবং &#038; লিখে সার্চ করুন। যদি এটি কোনো <script> ব্লকের ভেতরে পান, তবে বুঝবেন ফিল্টারটিই এর মূল কারণ। সমস্যাটি কনসোলে দেখা যাবে না কারণ ব্রাউজার পার্স করার জন্য কোনো সিনট্যাক্টিক্যালি ভ্যালিড স্ক্রিপ্ট পায় না।

পাল্টা যুক্তি: কেন wptexturize রাখা উচিত?

wptexturize ফ্রন্ট-এন্ডে পড়ার উপযোগিতা (readability) বৃদ্ধি করে। কার্লি কোট এবং সঠিক ড্যাশ ক্যারেক্টার গদ্যকে একটি মার্জিত রূপ দেয়, এবং অনেক সাইট মালিক এটিকে একটি অপরিহার্য নান্দনিক বৈশিষ্ট্য হিসেবে বিবেচনা করেন। গ্লোবালি ফিল্টারটি সরিয়ে ফেললে টেক্সট তার সাধারণ এবং টাইপোগ্রাফিক্যালি সাদামাটা অবস্থায় ফিরে যাবে।

এর একটি সমাধান হলো বাছাইকৃতভাবে নিষ্ক্রিয় করা (selective disabling): যেখানে কোড রয়েছে শুধুমাত্র সেখানেই ফিল্টারটি বন্ধ করে দিন, অথবা একটি কাস্টম শর্টকোড ব্যবহার করুন যা স্পষ্টভাবে তার আউটপুটকে texturizing থেকে নিরাপদ হিসেবে চিহ্নিত করে। WordPress ইতিমধ্যেই wp_kses_post এবং অন্যান্য sanitisation helpers প্রদান করে; ডেভেলপাররা উভয় সুবিধা বজায় রাখতে সেগুলোকে remove_filter কলের সাথে যুক্ত করতে পারেন।

পরবর্তীতে যা খেয়াল রাখতে হবে

WordPress core এখনও wptexturize-এ এমন কোনো পরিবর্তনের ঘোষণা দেয়নি যা স্বয়ংক্রিয়ভাবে <script> ট্যাগগুলোকে exempt রাখবে। যতক্ষণ না এমন কোনো পরিবর্তন আসছে, ডেভেলপারদের ম্যানুয়ালি তাদের ইনলাইন কোড সুরক্ষিত রাখতে হবে। ফিল্টারটিকে context-aware করার জন্য কোনো প্রস্তাব আসছে কি না তা দেখতে core development tracker-এর ওপর নজর রাখুন। ইতিমধ্যে, যে কোনো শর্টকোড বা পেজ বিল্ডার এলিমেন্ট যা JavaScript ইনজেক্ট করে তা অডিট করুন এবং উপরের তিনটি সমাধানের যেকোনো একটি প্রয়োগ করুন।

মূল কথা: যদি আপনার WordPress সাইটে ইনলাইন JavaScript চলে, তবে যাচাই করে নিন যে wptexturize নীরবে এটিকে পরিবর্তন (rewriting) করছে কি না। একটি মাত্র escaped ampersand পুরো ফিচারটিকে অকেজো করে দিতে পারে, এবং এর সমাধান সাধারণত কয়েক লাইন PHP কোড অথবা এক্সটার্নাল স্ক্রিপ্টে স্থানান্তরিত হওয়া।