آموزش کار با فیلتر در وردپرس

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

یک مثال ساده از کاربرد filter در وردپرس تغییر اندازهٔ خلاصه (excerpt) نوشته‌هاست. به‌طور پیشفرض هنگام نمایش خلاصه‌ای از یک نوشته (در صفحه بایگانی) وردپرس سعی می‌کند حداکثر ۵۵ کلمهٔ ابتدایی آن را نمایش دهد. اگر ما بخواهیم این عدد را تغییر دهیم، دو راه‌حل کلی داریم:

  1. مستقیماً درون هسته وردپرس دست ببریم و این مقدار را تغییر دهیم. که کارِ اشتباهی است؛ چون علاوه بر مشکلاتی که ممکن است ایجاد کند، وقتی به روزرسانی وردپرس را انجام دهیم، این تغییرات از بین می‌روند!
  2. با filterهای وردپرس این مقدار را تغییر دهیم.

وقتی وردپرس بخواهد خلاصهٔ یک نوشته را نمایش دهد، ابتدا تمام فیلتر هوک‌هایی (قلاب‌هایی) که به متغیر مربوطه (در این مثال: except_length) متصل هستند را اجرا می‌کند. سپس نتیجه نهایی را به کار می‌برد. این نتیجه می‌تواند همان عدد پیشفرض باشد یا تغییراتی روی آن صورت گرفته باشد.

فیلتر در وردپرس

فیلترها نوعی هوک در وردپرس هستند. hook (قلاب یا چنگک) مجموعه‌ای از رویدادها یا محل‌هایی هستند که توسعه‌دهنده‌های وردپرس می‌توانند عملیات‌هایی روی آن‌ها سوار کنند. اگر با این مفهوم آشنایی ندارید، آموزش هوک در وردپرس و انواع آن برایتان مفید خواهد بود.

در آموزش هوک‌ها گفتم فرض کنید که یک طناب داریم و برنامه‌نویس‌ها قرار هست قلاب‌هایی (hook) به آن آویزان کنند. وقتی می‌خواهیم اتفاقی بیوفتد، آن طناب را می‌کشیم تا قلاب‌های متصل به آن هم کشیده شود.

مشابه همین مثال، تابعی به نام apply_filters() داریم که شبیه به طناب عمل می‌کند. به کد زیر توجه کنید:

<?php
$length = 55;
$length = apply_filters('excerpt_length', $length);

نام طناب ما excerpt_length است. در آرگومان‌های بعدی (دوم به بعد) مقادیری را مشخص می‌کنیم که می‌خواهیم به توابعی که باید اجرا شوند (فیلترها) پاس داده شوند. این فیلترها همان قلاب‌هایی هست که این طناب وصل می‌شوند.

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

اگر تا به حال با filter وردپرس سر و کار نداشته‌اید، ممکن است تا به اینجای آموزش کمی گیج شده باشید! این اتفاق کاملاً عادی است! 🙂 ادامهٔ بحث را دنبال کنید تا ساختار آن را درک و کاربردهایش را متوجه شوید.

استفاده از فیلترهای وردپرس

تابعی به نام add_filter() در وردپرس داریم که چهار آرگومان ورودی دارد:

add_filter( $hook_name, $callback, $priority , $accepted_args )

دو پارامتر اول اجباری و سومی و چهارمی دارای مقدار پیشفرض (اختیاری) هستند.

  1. $hook_name : نام هوکی را مشخص می‌کند که می‌خواهیم برایش فیلتر بنویسیم. (طنابی که فیلترمان را به آن آویزان می‌کنیم.)
  2. $callback : تابعی است که صدا زده می‌شود. وقتی هوک مورد نظر اجرا شد (طناب کشیده شد) این تابع فراخوانی می‌شود.
  3. $priority : اولویت اجرای این فیلتر را مشخص می‌کند. فرض کنید برای یک هوک، چندین فیلتر داریم. در این صورت ابتدا فیلترهایی با عدد priority کمتر اجرا می‌شوند تا در نهایت به فیلترهایی با عدد اولویت بالاتر برسیم. (هر چه بیشتر، نسبت به بقیه فیلترها آخرتر اجرا می‌شود.)
  4. $accepter_args : مشخص می‌کند چه تعداد آرگومان (پارامتر ورودی) به تابع فیلتر ارسال می‌شود.

مقدار پیشفرض اولویت (priority) عدد 10 و تعداد آرگومان‌های قابل پذیرش 1 است.

بیایید طول خلاصه نوشته‌های وردپرس را تغییر دهیم. ابتدا یک فیلتر ایجاد می‌کنم:

<?php
add_filter('excerpt_length', 'change_the_excerpt_length');

حالا باید تابع فیلتر (همان callback) را تعریف کنیم:

<?php
function change_the_excerpt_length($length){
    return 16;
}

با ایجاد این فیلتر چه اتفاقی می‌اُفتد؟

وقتی اجرای کدها به خطی که حاوی apply_filters() (در اوایل آموزش) بود می‌رسد، سعی می‌کنید تمام فیلترهای متصل به آن را اجرا کرده و روی متغیر ما ($length) اعمال کند.

اگر فرض کنیم فقط همین فیلتر در تمام کدهای وردپرس برای این هوک وجود داشته باشد، این تابع مقدار ورودی (که 55 بود) را گرفته و عدد 16 را برمی‌گرداند. در اینجا من صرفاً یک عدد را برگرداندم و به مقدار ورودی هیچ کاری نداشتم. بنا به نیازمان می‌توانیم با ورودی نیز کارهایی انجام دهیم. مثلاً به جای آنکه 16 را برگردانیم، مقدار $length * 2 را برگردانیم.

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

مرور چگونگی اجرا

اجازه دهید قبل از ادامه، یک بار دیگر روند اجرای فیلتر را مرور کنم. همه کدهایی که تا الآن داشتیم را با کم تغییر پشتِ سرِ هم در باکس پایین می‌گذارم:

<?php
function show_post_excerpt(){
    // something

    $length = 55;
    $length = apply_filters('excerpt_length', $length);

    // something
}

add_filter('excerpt_length', 'change_the_excerpt_length');
function change_the_excerpt_length($length){
    return 16;
}

// test:
show_post_excerpt();

در این قطعه کد، تابع show_post_excerpt() در خط آخر فراخوانی می‌شود. در بدنهٔ این تابع مقدار متغیر $length برابر با 55 تعریف می‌شود. سپس یک فیلتر هوک در وردپرس با نام excerpt_length ایجاد شده و اجرا می‌شود.

وقتی apply_filters() صدا زده می‌شود، وردپرس سعی می‌کند تمام توابعی که به این هوک متصل شده‌اند را به ترتیب اولویت (از priority کوچک‌تر تا بزرگ‌تر) فراخوانی کند.

اینجا ما فقط یک add_filter برای هوک موردنظر داریم. بنابراین تابع change_the_exceprt_length() فراخوانی شده و مقدار 55 (مقدار فعلی $length در تابع apply_filters()) به عنوان پارامتر ورودی به آن ارجاع داده می‌شود.

این تابع مقدار 16 را به عنوان خروجی برمی‌گرداند. حالا این مقدار به جای apply_filter در بدنه تابع اولی قرار گرفته و مقدار متغیر ما برابر با 16 خواهد شد. سپس بقیهٔ کدها اجرا می‌شوند.

در آموزش تغییر نام و آدرس ایمیل فرستنده در وردپرس نیز از فیلتر هوک برای تغییر این مقادیر استفاده کرده‌ایم.

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

حذف فیلتر وردپرس با remove_filter

در وردپرس و برخی افزونه‌های آن (مثل ووکامرس) هوک‌های بسیاری وجود دارند که می‌توانیم روی آن‌ها فیلترهایی ایجاد کنیم. هر افزونه یا پوسته‌ای که استفاده می‌کنیم ممکن است فیلترهایی برای اعمال تغییرات موردنظرشان تعریف کرده باشند.

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

سپس با تابع remove_filter() آن را حذف کنیم. برای مثال، پس از اجرای قطعه کد زیر، تغییری که روی excerpt_length ایجاد کرده بودیم بی اثر خواهد شد. به عبارت دیگر، انگار که هیچ add_filterـی برای excerpt_length ننوشته‌ایم.

<?php
remove_filter('excerpt_length', 'change_the_excerpt_length');

علاوه بر نوشتن این کدها در functions.php می‌توانیم آن‌ها را با روش‌های دیگری نیز به سایتمان اضافه کنیم. در آموزش زیر تمام این روش‌ها بررسی شده‌اند:

افزودن کد به وردپرس : ۳ روش افزودن کد سفارشی PHP و CSS

افزودن کد به وردپرس : ۳ روش افزودن کد سفارشی PHP و CSS

ساخت filter جدید

تا اینجا توانستیم فیلتری ایجاد کنیم که روی هوک مورد نظرمان اعمال شود. اما اگر به عنوان توسعه‌دهنده افزونه یا پوستهٔ وردپرسی بخواهیم بعضی از مقادیرمان را به این امکان مجهز کنیم، چطور باید عمل کرد؟!

پیش‌تر با تابع apply_filters() آشنا شدید. این تابع تمام فیلترهای مربوطه را اجرا کرده و در نهایت فقط یک مقدار را به ما برمی‌گرداند. ما می‌توانیم هر تعداد پارامتر را به توابع فیلتر بدهیم اما در نهایت فقط یک مقدار به عنوان خروجی دریافت می‌کنیم.

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

فرض کنید می‌خواهیم تعدادی آیتم را به کاربر نمایش دهیم. همچنین به بقیهٔ توسعه‌دهنده‌ها اجازه دهیم اگر می‌خواهند این آیتم‌ها را قبل از نمایش دستکاری کنند.

<?php
function sbzd_show_items(){
    $items = ['python', 'php', 'java', 'rust', 'go'];
    $items = apply_filters('available_languages', $items);

    echo "<ul>";
    foreach($items as $item){
        echo "<li>{$item}</li>";
    }
    echo "</ul>";
}

در تابع بالا ابتدا یک متغیر تعریف کردم. سپس فیلترهای احتمالی را روی آن اعمال کرده و در نهایت با یک حلقه foreach در php اعضای آن را چاپ کرده‌ام. این کار صرفاً برای یادگیری است و بنا به نیاز سیستم ممکن است لازم باشد کار دیگری با آن‌ها انجام دهیم.

فیلتر سفارشی وردپرس با چند پارامتر

برای اینکه بیشتر از یک پارامتر برای فیلتر تعیین کنیم، کد بالا را کمی پیچیده‌تر می‌کنم. مثلاً مقدار ID نوشتهٔ فعلی را نیز ارجاع می‌دهم تا اگر توسعه‌دهنده‌ای خواست بر آن اساس تغییراتی ایجاد کند بتواند.

<?php
function sbzd_show_items(){
    $items = ['python', 'php', 'java', 'rust', 'go'];
    $post_id = get_the_ID();
    $items = apply_filters('available_languages', $items, $post_id);

    echo "<ul>";
    foreach($items as $item){
        echo "<li>{$item}</li>";
    }
    echo "</ul>";
}

حالا برای اینکه یک تابع فیلتر جدید اضافه کنیم، باید به صورت زیر عمل کنیم:

<?php
add_filter('available_languages', 'sbzd_change_languages', 10, 2);

function sbzd_change_languages($items, $pid){
	$items[] = 'sql';
    return $items;
}

دقت کنید که در add_filter() مقدار اولویت را همان مقدار پیشفرض (یعنی 10) ولی تعداد آرگومان‌ها را 2 تعیین کرده‌ام. همچنین در قطعه کد بالا هیچ استفاده‌از ای آرگومان دوم (یعنی $pid) نکردم؛ اما ممکن است یک فرد دیگر در یک فیلتر جدید از آن استفاده کند.

البته می‌توانستیم get_the_ID() را مستقیماً در تابع فیلتر صدا بزنیم؛ اما صرفاً برای اینکه از بیشتر از یک پارامتر در فیلترهای وردپرس استفاده کنیم آن را به عنوان آرگومان تعریف کردم. 😉

در این آموزش یاد گرفتیم چطور از فیلترهای وردپرس استفاده کنیم. فیلترها یکی از دو نوع هوک (hook : قلاب) در wordpress هستند که به ما اجازه می‌دهند با اتصال به محل‌های خاص، مقدار متغیرهای موردنظرمان را دستکاری کنیم. اگر با نوع دیگر هوک‌ها یعنی action آشنا نیستید، وقت آن است که بعد از یک تمرین کوتاه، به آموزش اکشن در وردپرس مراجعه کنید. 🙂

هر سؤال یا چالشی در استفاده از filterها دارید از بخش دیدگاه‌ها بفرستید.