Introduction
This post will show you how to create popular posts widget in WordPress without plugin. There are number of plugins available for displaying popular posts in your wordpress website but here I will show you how to create widget in WordPress, where you will display most popular posts by comments count on posts. The style for the widget will inherit from your site’s theme style.
This tutorial will assume that you have basic knowledge on WordPress and PHP coding.
Related Posts:
Prerequisites
WordPress 5.2.2 – 5.7, PHP 7.2 – 7.4.3
Note that the above versions I mentioned while I was writing code for this WordPress widget.
Go through the following sections in order to create popular posts widget in WordPress without plugin.
Remember to add the below code into your theme’s functions.php
file. If this file does not exist then you need to create it.
Creating WordPress Widget
First step is to know how to create widget in WordPress and for that you may go through WordPress Widget API.
I would not tell you here everything about the widget API of WordPress but I will only tell you what I am doing here.
Whenever you want to create a widget in WordPress, you need to extend WP_Widget class.
I have called parent constructor to set a default tile for the widget and description for the widget.
I have declared a function called widget()
that display what I want to display on widget. I have put a comment write code for determining popular posts
and I will tell you later how to retrieve popular posts from database using SQL statement.
I have declared another function called form()
that will ask for inputs, such as, title of the widget and number of popular posts to display in the widget. I have also provided the default title and number of posts to display if user does not give any value. By default the widget will show maximum 5 posts.
I have declared another function called update()
that updates the default title and number of posts to display in the widget.
So I have done creating the widget in WordPress. Now I need to register the newly created widget otherwise you won’t be able to see the widget under widgets area in WordPress Dashboard.
//Register Popular_Post_Widget widget
function register_popular_post_widget() {
register_widget( 'Popular_Post_Widget' );
}
add_action( 'widgets_init', 'register_popular_post_widget' );
The above code snippets have been used for registering the widget into wordpress.
/**
* Name: Popular Posts widget.
* Author: https://roytuts.com
*/
class Popular_Post_Widget extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'popular_post_widget', // Base ID
esc_html__( 'Popular Posts', 'text_domain' ), // Name
array( 'description' => esc_html__( 'A Popular Post Widget', 'text_domain' ), ) // Args
);
}
/**
* Front-end display of widget.
*
* @see WP_Widget::widget()
*
* @param array $args Widget arguments.
* @param array $instance Saved values from database.
*/
public function widget( $args, $instance ) {
$title = $instance['title'];
$postscount = $instance['posts'];
echo $args['before_widget'];
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
}
//write code for determining popular posts
echo $args['after_widget'];;
}
/**
* Back-end widget form.
*
* @see WP_Widget::form()
*
* @param array $instance Previously saved values from database.
*/
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'Popular Posts', 'text_domain' );
$posts = ! empty( $instance['posts'] ) ? $instance['posts'] : esc_html__( '5', 'text_domain' );
?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label>
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
<label for="<?php echo esc_attr( $this->get_field_id( 'posts' ) ); ?>"><?php esc_attr_e( 'Number of Posts:', 'text_domain' ); ?></label>
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'posts' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'posts' ) ); ?>" type="text" value="<?php echo esc_attr( $posts ); ?>">
</p>
<?php
}
/**
* Sanitize widget form values as they are saved.
*
* @see WP_Widget::update()
*
* @param array $new_instance Values just sent to be saved.
* @param array $old_instance Previously saved values from database.
*
* @return array Updated safe values to be saved.
*/
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
$instance['posts'] = ( ! empty( $new_instance['posts'] ) ) ? sanitize_text_field( $new_instance['posts'] ) : '';
return $instance;
}
}
// register Popular_Post_Widget widget
function register_popular_post_widget() {
register_widget( 'Popular_Post_Widget' );
}
add_action( 'widgets_init', 'register_popular_post_widget' );
Fetching Popular Posts
Now I will query the database and fetch the popular posts based on maximum number of comments on posts. I will fetch only number of rows given as an input for the Number of Posts to display in the widget.
Next replace the comment inside widget()
function as I told in previous section by below code snippets.
I execute query on posts table and fetch top (for example, here it is 5) rows which are having maximum comments for the posts.
?>
<ul>
<?php
global $wpdb;
$posts = $wpdb->get_results("SELECT comment_count, ID, post_title FROM $wpdb->posts ORDER BY comment_count DESC LIMIT 0, $postscount");
foreach ($posts as $post) {
setup_postdata($post);
$id = $post->ID;
$title = $post->post_title;
$count = $post->comment_count;
echo '<li><a href="' . get_permalink($id) . '" title="' . $title . '">' . $title . '</a></li>';
}
?>
</ul>
<?php
Adding Widget
Now you will see the newly created widget by navigating from Appearance -> Widgets as shown in the below image.

Notice widget’s title and description have been set through constructor and visible here.
Now you can add this Popular Posts widget in widget area of your theme.
Final Result
When you add this Popular Posts widget, for example, on right sidebar widget area, then your widget with popular posts will look similar to the below image.

How to create popular posts with pictures?
I am making a sidebar with popular posts. I need to show a picture from a publication.
How can I modify your code to show the image above the title?
Can you pls fix a popular post base on views instead of comments thanks….