«این متن تبلیغاتی را چطور از انتهای همه نوشته‌ها حذف کنم؟» — این سؤال را سال‌ها پیش از یک مشتری شنیدم که یک افزونهٔ جانبی، به‌طور خودکار یک امضای تبلیغاتی به انتهای هر نوشته اضافه می‌کرد و هیچ تنظیمی برای غیرفعال‌کردنش نداشت. من به‌جای ویرایش فایل افزونه (که در آپدیت بعدی پاک می‌شد)، یک remove_filter در چایلد تم نوشتم. سه خط کد، مشکل را برای همیشه حل کرد. از آن روز، حذف فیلتر هوک‌ها به یکی از مهارت‌های روزمرهٔ من در پروژه‌های وردپرسی تبدیل شد. اگر با مفاهیم پایه آشنا نیستید، پیش از ادامه هوک‌های وردپرس چیست، تفاوت اکشن و فیلتر در وردپرس و نحوه استفاده از add_filter را بخوانید. مکمل این مقاله حذف اکشن هوک وردپرس، مهم‌ترین فیلتر هوک‌های وردپرس، راهنمای حرفه‌ای کار با هوک‌ها و ساخت فیلتر سفارشی است.

فیلتر هوک چیست و چرا حذف آن لازم می‌شود؟

فیلتر هوک، نقطه‌ای در چرخه اجرای وردپرس است که داده‌ای به کد شما داده می‌شود، شما آن را تغییر می‌دهید و برمی‌گردانید. برخلاف اکشن که فقط یک رخداد را اعلام می‌کند، فیلتر همیشه یک مقدار می‌گیرد و همیشه یک مقدار برمی‌گرداند. اگر callback فیلتر شما مقدار را برنگرداند، وردپرس مقدار null می‌گیرد و محتوا یا صفحه سفید می‌شود. همین یک قاعده ساده، منبع شایع‌ترین باگ در پروژه‌های تازه‌کار است. توضیح کامل در هوک‌های وردپرس چیست و تفاوت اکشن و فیلتر.

حذف فیلتر هوک، در سه سناریوی اصلی لازم می‌شود:

  1. حذف یک قابلیت افزونه یا قالب دیگر: افزونه‌ای یک متن تبلیغاتی به انتهای هر نوشته اضافه می‌کند و راهی برای غیرفعال‌کردن آن ندارد. با remove_filter، بدون ویرایش کد افزونه، آن را حذف می‌کنید.
  2. تغییر رفتار قالب والد در چایلد تم: به‌جای override فایل‌های template، فیلترهای قالب والد را حذف و نسخهٔ سفارشی خود را جایگزین می‌کنید.
  3. جلوگیری از اجرای یک فیلتر در شرایط خاص: مثلاً می‌خواهید یک فیلتر فقط در صفحات خاص اجرا نشود. با remove_filter شرطی، این کار ممکن می‌شود.

راهنمای تکمیلی در هوک‌های وردپرس، ساختار هسته وردپرس، هوک‌ها در توسعه افزونه، هوک‌ها در توسعه قالب و هوک‌های خروجی قالب آمده است.

حذف فیلتر هوک، مثل برداشتن یک صافی از مسیر آب است: بدون شکستن لوله، جریان را از یک نقطهٔ خاص قطع می‌کنید.

تابع remove_filter: نحو و پارامترها

تابع اصلی حذف فیلتر، remove_filter است. نحو آن دقیقاً مشابه add_filter است:

remove_filter( $hook_name, $callback, $priority );

// مثال ساده
remove_filter( 'the_content', 'myplugin_add_footer_signature', 10 );

// حذف فیلتر با متد کلاس
remove_filter( 'the_content', array( 'My_Class', 'method_name' ), 20 );

سه پارامتر کلیدی: یک — نام هوک: رشته‌ای که نقطه اتصال را مشخص می‌کند. دو — callback: تابع یا متد کلاسی که باید حذف شود. سه — priority: عددی که در زمان ثبت استفاده شده است. اگر priority را اشتباه بدهید، حذف انجام نمی‌شود. راهنمای کامل در نحوه استفاده از add_filter، حذف اکشن هوک، Priority در هوک‌ها و کنترل ترتیب اجرای هوک‌ها.

نکته حیاتی: remove_filter باید بعد از ثبت فیلتر اجرا شود. اگر می‌خواهید فیلتر افزونه‌ای را حذف کنید، کد حذف شما باید بعد از bootstrap آن افزونه اجرا شود. معمولاً از هوک init با priority بالاتر یا wp_loaded استفاده می‌کنم. راهنمای کامل در هوک‌های وردپرس و راهنمای حرفه‌ای هوک‌ها.

اهمیت priority در حذف فیلتر

یکی از پرتکرارترین خطاها در حذف فیلتر، اشتباه در priority است. اگر فیلتر با priority ۱۰ ثبت شده باشد و شما با priority ۲۰ حذف کنید، حذف نمی‌شود. برای اطمینان، همیشه priority را دقیقاً مطابق با ثبت بدهید:

// ثبت با priority 15
add_filter( 'the_content', 'myplugin_append_text', 15 );

// حذف با همان priority
remove_filter( 'the_content', 'myplugin_append_text', 15 );

اگر از priority ثبت‌شده مطمئن نیستید، می‌توانید از global $wp_filter برای بررسی استفاده کنید:

global $wp_filter;
if ( isset( $wp_filter['the_content'] ) ) {
    error_log( print_r( $wp_filter['the_content'], true ) );
}

راهنمای دقیق priority در Priority در هوک‌ها، کنترل ترتیب اجرای هوک‌ها، پارامترهای هوک و استفاده درست از هوک‌ها آمده است.

priority در حذف فیلتر، مثل کلید در قفل است: اگر شمارهٔ کلید را اشتباه بدهید، قفل باز نمی‌شود.

حذف فیلتر از کلاس‌ها

بسیاری از افزونه‌ها و قالب‌های حرفه‌ای، فیلترها را در کلاس‌ها ثبت می‌کنند. برای حذف این فیلترها، باید نام کلاس و متد را دقیقاً مطابق با ثبت بدهید:

// ثبت در کلاس
class My_Plugin {
    public function __construct() {
        add_filter( 'the_content', array( $this, 'modify_content' ), 10 );
    }
    public function modify_content( $content ) { /* ... */ }
}

// حذف از کلاس
// اگر نمونهٔ کلاس در دسترس است:
$my_plugin = new My_Plugin();
remove_filter( 'the_content', array( $my_plugin, 'modify_content' ), 10 );

// یا اگر متد استاتیک است:
remove_filter( 'the_content', array( 'My_Plugin', 'modify_content' ), 10 );

نکته: اگر متد private یا protected باشد، حذف آن از بیرون کلاس ممکن نیست. در این حالت، باید از فیلتر یا روش‌های دیگر استفاده کنید. راهنمای کامل در کدنویسی اختصاصی افزونه، ساختار فایل‌های افزونه استاندارد، توسعه افزونه از صفر و اصول کدنویسی تمیز.

حذف فیلتر از قالب والد در چایلد تم

یکی از پرکاربردترین سناریوهای حذف فیلتر، حذف فیلترهای قالب والد در چایلد تم است. به‌جای override فایل‌های template، فیلترهای والد را حذف و نسخهٔ سفارشی خود را جایگزین می‌کنید:

// در functions.php چایلد تم
add_action( 'after_setup_theme', 'my_child_remove_parent_filters' );

function my_child_remove_parent_filters() {
    // حذف فیلتر قالب والد برای نمایش نویسنده
    remove_filter( 'the_content', 'mytheme_author_box', 10 );
    
    // افزودن نسخه سفارشی
    add_filter( 'the_content', 'my_child_author_box', 10 );
}

function my_child_author_box( $content ) {
    // نسخه سفارشی
    return $content;
}

نکته: حذف فیلتر والد باید پس از after_setup_theme انجام شود تا مطمئن شوید قالب والد توابع خود را ثبت کرده است. راهنمای کامل در قالب چایلد چیست، توسعه با چایلد تم، ساختار فایل‌های قالب استاندارد، توسعه قالب از صفر و هوک‌ها در توسعه قالب آمده است.

حذف فیلترهای افزونه‌های دیگر

گاهی نیاز دارید فیلترهای یک افزونهٔ دیگر را حذف کنید. برای این کار، باید نام دقیق تابع یا متد کلاس آن افزونه را بدانید. معمولاً با مراجعه به مستندات افزونه یا بررسی کد آن، این نام را پیدا می‌کنید:

// حذف فیلتر افزونه دیگر
remove_filter( 'the_content', 'other_plugin_add_banner' );

// اگر در کلاس است
remove_filter( 'the_content', array( 'Other_Plugin_Class', 'add_banner' ), 10 );

نکته: اگر فیلتر با closure ثبت شده باشد، قابل حذف نیست. این محدودیت، دلیل مهمی است که در افزونه‌های حرفه‌ای callbackها را به‌صورت متد کلاس یا تابع نام‌دار تعریف می‌کنیم. راهنمای کامل در حذف اکشن هوک، استفاده درست از هوک‌ها، اشتباهات رایج هوک‌ها، کدنویسی اختصاصی افزونه و ساختار فایل‌های افزونه استاندارد.

حذف فیلتر از افزونه دیگر، مثل برداشتن یک آجر از دیوار است: باید بدانید کدام آجر را بردارید تا دیوار فرو نریزد.

حذف فیلترهای شرطی

گاهی می‌خواهید یک فیلتر فقط در شرایط خاص حذف شود. مثلاً فقط در صفحهٔ اصلی، یا فقط برای کاربران مهمان. برای این کار، از حذف شرطی استفاده کنید:

add_action( 'wp', 'my_conditional_remove_filter' );

function my_conditional_remove_filter() {
    if ( is_front_page() && ! is_user_logged_in() ) {
        remove_filter( 'the_content', 'myplugin_add_footer_banner', 10 );
    }
}

نکته: هوک wp بعد از تشخیص نوع درخواست اجرا می‌شود و توابع شرطی مثل is_front_page در آن قابل اعتماد هستند. راهنمای کامل در هوک‌های وردپرس، استفاده درست از هوک‌ها، بررسی وضعیت ورود کاربر، توابع نقش و دسترسی و کنترل ترتیب اجرای هوک‌ها آمده است.

اشتباهات رایج در حذف فیلتر

فهرست کوتاه اما گران‌قیمت از اشتباهاتی که در کدهای بازبینی‌شده دیده‌ام:

  • priority اشتباه: شایع‌ترین اشتباه. اگر priority ثبت ۱۵ باشد و شما ۱۰ بدهید، حذف نمی‌شود. راهنما در Priority در هوک‌ها.
  • حذف قبل از ثبت: اگر کد حذف شما قبل از bootstrap افزونه اجرا شود، فیلتری برای حذف وجود ندارد. راهنما در کنترل ترتیب اجرای هوک‌ها.
  • حذف closure: فیلترهایی که با تابع ناشناس ثبت شده‌اند، قابل حذف نیستند. راهنما در استفاده درست از هوک‌ها.
  • نبود بررسی وجود فیلتر: اگر فیلتر وجود نداشته باشد، remove_filter خطا نمی‌دهد ولی کاری هم نمی‌کند. برای اطمینان، از has_filter استفاده کنید. راهنما در توابع دیباگ وردپرس.
  • حذف از قالب والد به‌جای چایلد: اگر در قالب والد حذف کنید، با آپدیت قالب، حذف شما پاک می‌شود. راهنما در قالب چایلد چیست.
  • نبود مستندسازی: سه ماه بعد، دلیل حذف فیلتر گم می‌شود. راهنما در اصول کدنویسی تمیز.

فهرست کامل اشتباهات در اشتباهات رایج هوک‌ها، اشتباهات رایج توسعه وردپرس و اشتباهات رایج کدنویسی وردپرس آمده است.

دیباگ فیلترهای حذف‌شده

وقتی فیلتری حذف نمی‌شود، سه ابزار در پروژه‌های خودم استفاده می‌کنم:

یک تجربه میدانی: در پروژه‌ای، یک فیلتر حذف نمی‌شد. با global $wp_filter، کشف شد که افزونه‌ای دیگر همان callback را با priority متفاوت ثبت کرده و حذف ما فقط یکی از آن‌ها را برداشته است. با حذف هر دو priority، مشکل حل شد. راهنمای کامل در تست و دیباگ پروژه‌های وردپرس، دیباگ کد سفارشی و خطای Deprecated در PHP.

بهترین روش‌ها و الگوهای حرفه‌ای

در پروژه‌های بزرگ، حذف فیلترها را در یک نقطه متمرکز کنید:

class My_Plugin_Remove_Filters {
    public static function init() {
        add_action( 'after_setup_theme', array( __CLASS__, 'remove_parent_filters' ) );
        add_action( 'wp', array( __CLASS__, 'conditional_removals' ) );
    }

    public static function remove_parent_filters() {
        remove_filter( 'the_content', 'mytheme_author_box', 10 );
    }

    public static function conditional_removals() {
        if ( is_front_page() ) {
            remove_filter( 'the_content', 'myplugin_add_banner', 10 );
        }
    }
}
My_Plugin_Remove_Filters::init();

مزیت: خوانایی، امکان تست، و مدیریت ترتیب اجرا. الگوهای مشابه در کدنویسی اختصاصی افزونه، ساختار فایل‌های افزونه استاندارد، توسعه افزونه از صفر، استانداردهای کدنویسی وردپرس، بهینه‌سازی کد وردپرس و ساختاربندی پروژه وردپرس آمده است.

یک تجربه میدانی: در پروژه‌ای با سه افزونه اختصاصی که هرکدام چند فیلتر را حذف می‌کردند، انتقال به این الگو در یک کلاس متمرکز، زمان دیباگ تعارض‌ها را از چند ساعت به چند دقیقه کاهش داد.

حذف فیلتر در ووکامرس: مثال‌های واقعی

در فروشگاه‌های ووکامرسی، حذف فیلترها برای سفارشی‌سازی رابط کاربری ضروری است:

// حذف فیلتر تغییر قیمت نمایشی محصول
remove_filter( 'woocommerce_get_price_html', 'other_plugin_price_html', 10 );

// حذف فیلتر متن دکمه افزودن به سبد
remove_filter( 'woocommerce_product_single_add_to_cart_text', 'other_plugin_add_to_cart_text', 10 );

// حذف فیلتر نام محصول در ایمیل سفارش
remove_filter( 'woocommerce_order_item_name', 'other_plugin_order_item_name', 10 );

راهنمای کامل در هوک‌های ووکامرس، مدیریت سفارش‌های ووکامرس، سفارشی‌سازی صفحه محصول، سفارشی‌سازی سبد و تسویه‌حساب، راهنمای کار با ووکامرس و ووکامرس چیست آمده است.

جمع‌بندی

حذف فیلتر هوک در وردپرس، در چهار اصل خلاصه می‌شود: شناخت دقیق priority، اجرای حذف پس از ثبت، استفاده از callback نام‌دار، و متمرکزسازی حذف‌ها در یک کلاس. سه اصل را در پایان تاکید می‌کنم: اول، همیشه priority را مطابق با ثبت بدهید. دوم، حذف را در چایلد تم یا افزونه اختصاصی انجام دهید، نه در قالب والد. سوم، از حذف closureها پرهیز کنید؛ اگر افزونه‌ای closure دارد، به‌جای حذف، از فیلترهای دیگر استفاده کنید.

اگر امروز یک کار در این مسیر انجام می‌دهید: در پروژه فعلی خود، فهرست فیلترهایی که افزونه‌ها یا قالب اضافه کرده‌اند و شما نمی‌خواهید را بنویسید و برای هرکدام یک remove_filter با priority درست بنویسید. همان یک بازبینی، در آپدیت بعدی نجات‌دهنده است. اگر تجربه‌ای از یک حذف فیلتر دارید که پروژه‌ای را نجات داد یا باگی را حل کرد، در دیدگاه‌ها بنویسید — همان گزارش‌های واقعی، این راهنما را برای توسعه‌دهنده بعدی دقیق‌تر می‌کند. 🔗