آموزش ساخت ابزارک(ویجت) آخرین نظرات کاربران در وردپرس

transient و نمایش آخرین کامنت ها

در یکی دیگر از آموزش های توسعه وردپرس قصد داریم یک ابزارک(ویجت/Widget) اختصاصی برای نمایش آخرین نظرات کاربران بنویسیم، البته این ویجت به صورت پیش فرض با نام “آخرین دیدگاه ها” در بخش ابزارک های پنل مدیریتی وردپرس موجود است و می توانید از آن استفاده کنید.

پس چرا ما به دنبال تولید یک ویجت اختصاصی هستیم و می خواهیم کاری تکراری انجام دهیم، دلایل زیر ممکن است برای شما قانع کننده باشد:

  • شخصی سازی بهتر و افزودن تنظیمات بیشتر به ابزارک
  • کش کردن آخرین نظرات کاربران به منظور افزایش سرعت سایت
  • کوئری نویسی اختصاصی به منظور کاهش سربار دیتابیس

اگر مجاب شدید که تا انتهای این آموزش همراه ما باشید پیشنهاد می کنیم ابتدا مقالات روش های کوئری نویسی سفارشی(Custom Query) در وردپرس و آموزش کش کردن داده ها در وردپرس با Transients API + مثال عملی را مطالعه فرمائید، چرا که از تکنیک های گفته شده در این آموزش استفاده خواهیم کرد.

در ادامه مراحل پیاده سازی ابزارک آخرین نظرات کاربران را به صورت گام به گام بررسی می کنیم، تصویر زیر نمونه کامل شده این ابزارک است.

ویجت آخرین دیدگاه های کاربران

گام ۱: ایجاد فایل widgets.php

ابتدا در قالب وب سایت تان یک دایرکتوری به نام inc یا includes ایجاد کرده و در داخل آن یک فایل با نام دلخواه widgets.php ایجاد کنید، از این فایل می توانید در آینده برای تعریف سایر ویجت های وب سایت تان استفاده نمائید.

حالا کدهای زیر را در فایل widgets.php قرار دهید.

<?php
class Modiredev_Recent_Comments_Widget extends WP_Widget
{
	
}

add_action( 'widgets_init', function () {
    register_widget( 'Modiredev_Recent_Comments_Widget' );
});

 

چند نکته در رابطه با کدهای بالا:

  • یک کلاس به نام Modiredev_Recent_Comments_Widget ایجاد کردیم که از کلاس پایه ای WP_Widget ارث بری کرده است، ویجت های وردپرس ابتدا باید از WP_Widget اکستند شوند، با اینکار می توانید متدها(همان توابع هستند ولی در داخل کلاس به آنها متد می گویند) و خصوصیات کلاس WP_Widget را در داخل کلاس اختصاصی خودتان فراخوانی و استفاده کنید.
  • از تابع register_widget برای معرفی و ثبت ویجت استفاده می کنیم، همانطور که ملاحظه می کنید کلاس Modiredev_Recent_Comments_Widget به عنوان پارامتر ورودی ارسال شده است.

گام ۲: فراخوانی سازنده کلاس(Constructor)

در این مرحله برخی خصوصیات ویجت را مشخص می کنیم، پس گام قبل را بدین صورت کامل کنید.

<?php
class Modiredev_Recent_Comments_Widget extends WP_Widget
{
  
  public function __construct()
    {
        $widget_options = array(
            'classname' => 'compact-posts-list',
            'description' => 'ویجت نمایش آخرین کامنت های وب سایت'
        );
        parent::__construct( 'modiredev-recent-comments', 'نمایش آخرین کامنت ها (مدیر دِو)', $widget_options );
    } 	
}

add_action( 'widgets_init', function () {
    register_widget( 'Modiredev_Recent_Comments_Widget' );
});

 

چند نکته در رابطه با کدهای بالا:

  • سازنده کلاس، متدی است که به محض ایجاد یک نمونه(Instance) یا آبجکت(Object) از یک کلاس فراخوانی و اجرا می شود.
  • در زبان PHP سازنده کلاس با کلمه کلیدی construct__ تعریف می شود و حتما باید public باشد.
  • آی دی، عنوان و توضیحات ویجت را با فراخوانی parent::__construct به سازنده والد(Parent) که متعلق به کلاس WP_Widget است ارسال می کنیم.
  • compact-posts-list یک کلاس اختیاری و دلخواه CSS است که می توانید از آن برای استایل دهی به ویجت استفاده کنید.

گام ۳: فایل functions.php

برای اینکه مطمئن شویم تا اینجای کار به درستی انجام شده است فایل widgets.php را به functions.php معرفی می کنیم، برای این منظور لازم است کد زیر را به ابتدای فایل functions.php اضافه نمائید.

include get_template_directory() . '/includes/widgets.php';

 

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

ویجت آخرین نظرات کاربران وردپرس

گام ۴: فرم تنظیمات ویجت در پنل مدیریتی وردپرس

در این مرحله فیلدهای موردنیاز ابزارک شامل عنوان، تعداد کامنت ها و نمایش یا عدم نمایش آواتار کاربران را مشخص می کنیم، برای این منظور از متد form کلاس WP_Widget استفاده می شود.

کدهای زیر را در ادامه موارد قبلی به کلاس Modiredev_Recent_Comments_Widget اضافه کنید.

public function form( $instance )
    {
        $widget_title = ( isset( $instance['title'] ) ? $instance['title'] : 'آخرین کامنت ها' );
        $post_count = ( isset( $instance['count'] ) ? $instance['count'] : 6 );
        $show_avatar_commenter = ( isset( $instance['show_avatar'] ) ? $instance['show_avatar'] : 1 );

        $output = '<p>';
        $output .= '<label for="' . esc_attr( $this->get_field_id('title') ) . '">';
        $output .= 'عنوان:';
        $output .= '</label>';
        $output .= '<input type="text"
                          class="widefat"
                          id="' . esc_attr( $this->get_field_id('title') ) . '"
                          name="' . esc_attr( $this->get_field_name('title') ) . '"
                          value="' . esc_attr( $widget_title ) . '">';
        $output .= '</p>';

        $output .= '<p>';
        $output .= '<label for="' . esc_attr( $this->get_field_id('count') ) . '">';
        $output .= 'تعداد کامنت هایی که نشان داده می شود:';
        $output .= '</label>';
        $output .= '<input type="number"
                         class="tiny-text"
                         id="' . esc_attr( $this->get_field_id('count') ) . '"
                         name="' . esc_attr( $this->get_field_name('count') ) . '"
                         value ="' . $post_count . '">';
        $output .= '</p>';

        $output .= '<p>';
        $output .= '<input type="checkbox"
                          id="' . esc_attr( $this->get_field_id('show_avatar') ) . '"
                          name="' . esc_attr( $this->get_field_name('show_avatar') ) . '"' .
            ( $show_avatar_commenter ? 'checked="checked"' : '') . '>';
        $output .= '<label for="' . esc_attr( $this->get_field_id('show_avatar') ) . '">';
        $output .= 'نمایش آواتار کاربر؟';
        $output .= '</label>';
        $output .= '</p>';
        echo $output;
    }

 

چند نکته در رابطه با کدهای بالا:

  • در پارامتر instance$ تنظیمات جاری ویجت نگهداری می شود.
  • title، count و show_avatar نام دلخواه فیلدهایی است که برای تنظیمات ویجت در نظر گرفتیم، این فیلدها در هنگام ذخیره ویجت(گام بعدی) استفاده خواهند شد، مقادیر پیش فرض آنها به ترتیب “آخرین کامنت ها”، “۶” و “۱” می باشد.
  • از تابع esc_attr برای اعتبارسنجی ورودی های کاربر استفاده شده است.
  • متدهای get_field_id و get_field_name به ترتیب برای تولید خصوصیت id و name فیلدهای ویجت کاربرد دارند.

اگر مجددا به صفحه ابزارک ها در پنل مدیریتی مراجعه کنید، نتیجه زیر را مشاهده خواهید کرد.

متد form کلاس wp_widget

گام ۵: ذخیره تنظیمات ویجت

در گام قبل فیلدهای ویجت را مشخص کردیم، اما مقادیر جدید این فیلدها آپدیت نمی شود، لازم است در این مرحله با فراخوانی متد update کلاس WP_Widget امکان بروزرسانی تغییرات را فراهم کنیم. برای این منظور کدهای زیر به کلاس Modiredev_Recent_Comments_Widget اضافه کنید.

public function update( $new_instance, $old_instance )
    {
        $instance = $old_instance;
        $instance['title'] = strip_tags( $new_instance['title'] );
        $instance['count'] = absint( $new_instance['count'] );
        $instance['show_avatar'] = ( $new_instance['show_avatar'] ? 1 : 0 );

        delete_transient( 'modiredev_recent_comments' );

        return $instance;
    }

 

چند نکته در رابطه با کدهای بالا:

  • با کلیک بر روی گزینه “ذخیره” ویجت، متد update اجرا خواهد شد و مقادیر جدید new_instance$ بر روی مقادیر قدیمی old_instance$ بازنویسی می شود.
  • از تابع strip_tags برای اعتبارسنجی ورودی کاربر استفاده شده است.
  • اگر در فیلد “تعداد کامنت هایی که نشان داده می شود” مقدار منفی یا غیرعددی وارد شود تابع absint آن را به یک عدد صحیح مثبت تبدیل می کند.
  • در گام بعد کامنت های کاربران را بر اساس تنظیمات ویجت فراخوانی و در دیتابیس کش می کنیم، به عنوان مثال اگر تعداد “کامنت هایی که نمایش داده می شود” بر روی ۵ تنظیم شده باشد فقط ۵ کامنت آخر را نمایش خواهیم داد. با این حال اگر بعدا بخواهیم عدد فوق را کمتر یا بیشتر کنیم کاربران همچنان ۵ دیدگاه آخر را مشاهده خواهند کرد و وردپرس متوجه تغییرات جدید نخواهد شد، از این رو در متد update تابع delete_transient را فراخوانی کردیم تا داده های کش شده قدیمی حذف و داده های جدید کش شوند.

گام ۶: نمایش آخرین کامنت های کاربران

تا این مرحله هر کدی که نوشتیم مختص بخش ابزارک ها در پنل مدیریتی وردپرس بود، در این گام می خواهیم آخرین کامنت های کاربران را بر اساس تنظیمات ویجت نمایش دهیم، برای این منظور از متد widget کلاس WP_Widget استفاده می کنیم.

برای تکمیل ویجت کدهای زیر را در ادامه موارد قبلی به کلاس Modiredev_Recent_Comments_Widget اضافه کنید.

public function widget( $args, $instance )
    {
        $comments_count = $instance['count'];
        $show_avatar = $instance['show_avatar'];

        $latest_comments = get_transient( 'modiredev_recent_comments' );

        if ( $latest_comments === false ) {
            global $wpdb;
            $latest_comments = $wpdb->get_results(
                $wpdb->prepare(
                "SELECT  c.comment_ID,c.comment_author_email,
                         c.comment_author,
                         p.post_title,p.post_name 
                      FROM $wpdb->comments c
                       INNER JOIN $wpdb->posts p ON c.comment_post_id=p.ID
        	            WHERE c.comment_approved='1' 
        	            ORDER BY c.comment_ID DESC LIMIT 0 , %d",
                $comments_count
                )
            );
            set_transient( 'modiredev_recent_comments', $latest_comments, YEAR_IN_SECONDS );
        }


        if ( $latest_comments ) {
            echo $args['before_widget'];

            if ( ! empty( $instance['title'] ) ) {
                echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
            }

            echo '<div class="widget-content">';
            foreach ( $latest_comments as $comment ) :
                echo '<article class="blog-post">';
                if ($show_avatar) {
                    echo '<figure class="post-thumbnail">';
                    echo get_avatar( $comment->comment_author_email );
                    echo '</figure>';
                }
                echo '<header class="entry-header">';
                echo '<p class="post-comment-title">';
                echo '<span class="comment_author">' . $comment->comment_author . "</span> در ";
                echo '<a href="' . get_bloginfo('url') . '/' . $comment->post_name .
                                                         '/#comment-' . $comment->comment_ID .
                                                         '" target="_blank">';
                echo $comment->post_title . '</a>';
                echo '</p>';
                echo '</header>';
                echo '</article>';
            endforeach;
            echo '</div>';
            echo $args['after_widget'];
        }
    }

 

چند نکته در رابطه با کدهای بالا:

  • ابتدا با تابع get_transient داده های کش شده را فراخوانی کرده و در متغیر latest_comments$ نگهداری می کنیم.
  • اگر داده ای کش نشده باشد شرط latest_comments === false$ برقرار خواهد بود و تابع set_transient نتیجه اجرای کوئری را کش کرده و در دیتابیس ذخیره می کند.
  • مدت زمان انقضاء کش یکسال( YEAR_IN_SECONDS )  است.
  • در آرگومان args$ مقادیر before_title ،after_title ،before_widget و after_widget وجود دارد، این مقادیر در هنگام تعریف سایدبار مشخص می شوند.
  • در حلقه foreach به ازای هر کامنت HTML و کلاس های CSS مدنظر را تولید کردیم، این ساختار بسته به هدف و نیاز شما متفاوت خواهد بود.

گام ۷: تایید دیدگاه کاربران

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

برای این منظور لازم است کدهای زیر را به فایل functions.php اضافه نمائید. تابع modiredev_delete_transient_recent_comments در هنگام ویرایش یا تغییر وضعیت یک کامنت(منوی دیدگاه ها) اجرا خواهد شد.

function modiredev_delete_transient_recent_comments()
{
    delete_transient( 'modiredev_recent_comments' );
}

add_action( 'wp_set_comment_status', 'modiredev_delete_transient_recent_comments' );
add_action( 'edit_comment', 'modiredev_delete_transient_recent_comments' );

 

جمع بندی

در این آموزش سعی کردیم از برخی تکنیک های پیشرفته در کدنویسی ابزارک آخرین نظرات کاربران استفاده کنیم، مطمئنا این روش ها بر روی سرعت و عملکرد بهتر یک وب سایت تاثیرگذار خواهد بود. البته در مخزن وردپرس افزونه های مختلفی مثل Better Recent Comments وجود دارد که می تواند بدون درگیری با کدهای PHP از آنها استفاده نمائید.

برچسب ها
سعید یاورنیا 117 نوشته 118 دیدگاه

توسعه دهنده وب، کارشناس ارشد نرم افزار.

دیدگاهتان را بنویسید.

نشانی ایمیل شما منتشر نخواهد شد، بخش‌های موردنیاز با * مشخص شده‌اند.