WordPress
Article

Creating a “Most-Commented-on Posts” Plugin for WordPress

By Narayan Prusty

Fresh content on any site is a good thing. A nice touch is to display your most discussed posts to your website visitors. In the case of WordPress, a widget is the ideal place for this. Users who wouldn’t otherwise know where to go after reading the current post, might check out and hopefully participate in your blog’s most commented posts. Your most commented on posts are commonly also the ones which bring most page views and are the most interesting.

In this tutorial we will create a basic plugin to display most commented on posts in a widget. Although there are lots of plugins available for this purpose, many of them tend to be overwhelming and also don’t support caching. In this article, the plugin we’ll build will be lightweight and will cache the top 10 commented posts for 24 hours.

Plugin Directory and Files

To start with the plugin development, create a directory called most-commented-widget and create the following files in it:

--most-commented-widget
  -most-commented-widget.php
  -style.css

In the most-commented-widget.php file, add the following text to make the plugin installable.

<?php

/*
Plugin Name: Most Commented Posts Widget
Plugin URI: http://sitepoint.com
Description: Displays most commented posts in an widget
Author: Narayan Prusty
*/

The get_posts() Function

We will use the get_posts() function instead of the WP_Query object to retrieve the most commented on posts, because using WP_Query directly alters the main loop (i.e., global $wp_query variable) which would cause site issues.

The get_posts() function is used to retrieve an array of WP_Post objects based on a set of parameters. get_posts() internally uses WP_Query object’s query function to construct a MySQL query and execute it. WP_Query object’s query doesn’t alter the main loop.

The Transients API

The Transients API is used to store key value pairs of data, just like the Options API, but with an expiration time. The Transients API stores the data only in cache if persistence caching is configured. Therefore the Transients API is great for caching data.

We will use the Transients API to cache our most commented posts for 24 hours.

Creating a Widget

OK, let’s create our widget. A widget is a class which extends the WP_Widget class. Here’s the code:

class Most_Commented_Post_Widget extends WP_Widget 
{
    public function __construct() 
    {
        parent::__construct("Most_Commented_Post_Widget", "Display Most Commented Posts", array("description" => __("This plugin displays three most commented posts in an widget")));
    }
         
    public function form($instance) 
    {
        if($instance) 
        {
            $title = esc_attr($instance['title']);
        } 
        else
        {
            $title = '';
        }
        ?>
 
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>"><?php echo "Title"; ?></label>  
            <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
        </p>
 
        <?php
    }
         
    public function update($new_instance, $old_instance) 
    {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        return $instance;
    }
         
    public function widget($args, $instance) 
    {
        extract($args);
        
        $title = apply_filters('widget_title', $instance['title']);
        
        echo $before_widget;

        if($title) 
        {
            echo $before_title . $title . $after_title ;
        }

        echo $after_widget;
    }
}

function register_most_commented_widget() 
{
  register_widget("Most_Commented_Post_Widget");
}

add_action("widgets_init", "register_most_commented_widget");

Here’s how the code works:

  • We are registering the widget class using the register_widget function which is called inside the widgets_init action.
  • The widget function of our Most_Commented_Post_Widget class is responsible for echoing the front end output.
  • At present, we’re just displaying the title on the front end.

Retrieving and Displaying the Most Commented On Posts

Here is the implementation of the widget function of the Most_Commented_Post_Widget class which displays the top 10 most commented on posts:

public function widget($args, $instance) 
{
    extract($args);
    
    $title = apply_filters('widget_title', $instance['title']);
    
    echo $before_widget;

    if($title) 
    {
        echo $before_title . $title . $after_title ;
    }

    $posts = null;

    $posts = get_posts(array(
    	'orderby'	=> 'comment_count',
    	'order'     => 'DESC',
    	'posts_per_page' => 10
	));

	?><ul class="most-commented-post-widget"><?php

        foreach ($posts as $key => $value) 
        {
        	$title = $value->post_title;
        	$comment_count = $value->comment_count;
        	$url = get_permalink($value->ID);

        	?>
        	<li>
        		<a href="<?php echo $url; ?>"><?php echo $title; ?></a>
        		<br>
        		<small><?php echo $comment_count; ?> comments</small>
        	</li>
        	<?php

        }

    ?></ul><?php
    echo $after_widget;
}

Here is how the code works:

  • We’re calling the get_posts function with orderby, order and posts_per_page array keys. We are retrieving the top 10 most commented on posts in descending order.
  • And then we’re using a foreach construct to loop through the array of the WP_Post objects.
  • We’re then displaying the title and the number of comments.

This is how our widget looks at present:

WordPress Comment Widget 1

But we haven’t started caching the result, yet. Let’s see how to cache the get_posts() result.

Caching the Most Commented On Posts List

Let’s see how we can implement the Transients API in our widget. Here’s the code of the widget function with the Transients API implementation:

public function widget($args, $instance) 
{
    extract($args);
    
    $title = apply_filters('widget_title', $instance['title']);
    
    echo $before_widget;

    if($title) 
    {
        echo $before_title . $title . $after_title ;
    }

    $posts = null;

    if(get_transient("most_commented_posts") == false)
    {
    	$posts = get_posts(array(
	    	'orderby'	=> 'comment_count',
	    	'order'     => 'DESC',
	    	'posts_per_page' => 10
		));

    	set_transient("most_commented_posts", json_encode($posts), 86400);
    }
    else
    {
    	$posts = get_transient("most_commented_posts");
    	$posts = json_decode($posts);
    }

	?><ul class="most-commented-post-widget"><?php

        foreach ($posts as $key => $value) 
        {
        	$title = $value->post_title;
        	$comment_count = $value->comment_count;
        	$url = get_permalink($value->ID);

        	?>
        	<li>
        		<a href="<?php echo $url; ?>"><?php echo $title; ?></a>
        		<br>
        		<small><?php echo $comment_count; ?> comments</small>
        	</li>
        	<?php

        }

    ?></ul><?php
    echo $after_widget;
}

Here, we’re storing the resultant array as a transient with a expiration timer for 24 hours. If the transient returns false, then we’re running the query again and storing the result as a transient for next 24 hours. Now the plugin will play much nicer with MySQL.

Styling the Widget

Let’s style our widget to look more professional. Put this code in the plugin file to enqueue the style.css file.

function most_commented_widget_style() 
{
    wp_register_style("most-commented-post-widget-style", plugin_dir_url(__FILE__) . "style.css");
    wp_enqueue_style("most-commented-post-widget-style");
}

add_action("wp_enqueue_scripts", "most_commented_widget_style");

Place this code in the style.css file to style the lists and add some margin.

.most-commented-post-widget
{
	list-style: none;
}

.most-commented-post-widget li
{
	margin-bottom: 20px;
}

This is what our widget should now look like:

WordPress Comment Widget Finished

Conclusion

In this article I’ve shown you how to easily build your own Most Commented On Posts plugin for WordPress. You can now go ahead and expand on this to display images and add more information. Please share your experience with your own plugins below.

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

Comments
collizo4sky

Great article as always @narayanprusty

For the sake of non-technical users, a link to download the plugin at the end of the tutorial will be very much appreciated.

narayanprusty

Thanks for the suggestion @collizo4sky

I will update the article with a link to download the plugin directly.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in WordPress, once a week, for free.