custom wordpress widget

How To Create Custom WordPress Widget – Complete Guide

custom wordpress widget

In this article, we will be creating an extended version of the ‘Recent Posts’ widget ‘Custom WordPress Widget’. Also, in order to follow these instructions, you will need a working WordPress install on a local machine or a hosting server and a text editor, like Notepad++. So, the ‘Recent Posts’ widget is actually a part of WordPress installation and it comes in a very basic form – just post titles with hyperlinks.

Therefore, I will create a different version that features a post thumbnail, post title and a very small excerpt with all of it styled to stand out. Disclaimer – don’t take any design advice from me.

***CAUTION*** I advise creating and testing your widget on a local WordPress installation (or at least a test site). Also, mistakes can cause fatal errors and crash the site, thereby causing inconvenience for your users.

 

Widget directory

Therefore, any WordPress add-on, regardless of being a plugin or a widget, will need to have its own directory in the ‘plugins’ and at least one PHP file.

So, let’s start by creating a directory.

To sum up, navigate to ‘wp-content/plugins’ directory and create a folder. Also, you can name it anything you want. In our case, it will be ‘fixrunner-custom-widget’.

fixrunner wordpress custom widget

After that, create a PHP file.

Also, you can name it anything you want as long as it ends with the ‘.php’ extension. Finally, I have named my plugin file ‘fixrunner-widget-plugin.php’.

 

Copy and paste this in your plugin file and we will edit it later on:

 

<?php

/*

Plugin Name: Fixrunner Custom Widget

Plugin URI: https://fixrunner.com/creating-a-custom-widget

Description: A custom widget. That’s it.

Version: 1.0

Author: Fixrunner

Author URI: https://fixrunner.com

License: GPL2

*/

class My_Widget extends WP_Widget {

// class constructor

public function __construct() {}

// output the widget content on the front-end

public function widget( $args, $instance ) {}

// output the option form field in admin Widgets screen

public function form( $instance ) {}

// save options

public function update( $new_instance, $old_instance ) {}

}

// Register the widget

function my_register_custom_widget() {

register_widget( ‘Fixrunner_Custom_Widget’ );

}

add_action( ‘widgets_init’, ‘my_register_custom_widget’ );

 

Additionally, if you wish to style your widget beforehand, rather than styling it through the ‘Additional CSS’ or theme stylesheet, you will need a CSS file as well. So, create a CSS file. You guessed it – any name is good as long as it ends with ‘.css’ extension. Also, you will need to enqueue the stylesheet by using the following code (adjust the parts of the code to fit the name of your file):

 

wp_enqueue_style( ‘fr-style’, plugins_url( ‘fr-style.css’, __FILE__ ), ”, ‘1.0’ );

Therefore, let’s move on with constructing the widget. Also, there are 5 essential parts of the widget:

  1. Header and hook
  2. __construct() – The Class Constructor
  3. widget() – The content of the widget displayed on the front-end
  4. form() – The backend form of the widget displayed in the ‘Widgets’ section
  5. update() – The part that defines how the widget and its options are updated

We will go through each of them one by one.

 

Header and hook

This can be considered as the widget wrapper since everything else goes in between.

The header of the widget is where we define the name, author, description and other information, visible in the ‘Plugins’ section of the ‘wp-admin’ dashboard. Also, in the image below, you will see an example of the plugin/widget header.

creating a custom widget

Also, the hook will be at the very bottom of the file (which you already added):

 

// Register the widget

function my_register_custom_widget() {

register_widget( ‘Fixrunner_Custom_Widget’ );

}

add_action( ‘widgets_init’, ‘my_register_custom_widget’ );

Finally, this registers the widget and allows it to be displayed in the ‘Plugin’ section and activated.

custom wordpress widget plugin

Therefore, if you followed the instructions above correctly, you will see your widget appearing under ‘Plugins’ section. It will not have any functionality yet, but we’ll deal with that in the following sections.

 

The Class Constructor – __construct()

This is a part of the code that defines the unique widget ID, title and options (which can vary). Also, here, we are defining the ID, name, and options ‘classname’, ‘description’, ‘customize_selective_refresh’. The last one (customize_selective_refresh) allows for changes to be visible when using the ‘Customizer’ (Appearance -> Customize) without refreshing the page.

 

class Fixrunner_Custom_Widget extends WP_Widget {

// Main constructor

public function __construct() {

$widget_ops = array(

‘classname’ => ‘fixrunner_custom_widget’,

‘description’ => ‘A plugin for Fixrunner readers.’,

‘customize_selective_refresh’ => true,

);

parent::__construct( ‘fixrunner_custom_widget’, ‘Fixrunner Custom Widget’, $widget_ops );

}

The ‘Description’ part is different from the header description. This description is visible under Appearance->Widgets:

 

The widget content using ‘widget()’ function

So, this is the actual frontend of the widget. Also, what you write here will be displayed on your site. Therefore, in our case, there’s a substantial bit of the code (for those unfamiliar with PHP), but I’ve put in the comments to explain what the lines are for. Also, since we are not going to go into detail for every line of code you might need to Google some of them:

 

//defining the frontend part

public function widget( $args, $instance ) {

if ( ! isset( $args[‘widget_id’] ) ) {

$args[‘widget_id’] = $this->id;

}

//getting the title from the backend

$title = ( ! empty( $instance[‘title’] ) ) ? $instance[‘title’] : __( ‘Recent Posts’ );

$title = apply_filters( ‘widget_title’, $title, $instance, $this->id_base );

//getting the number of posts from the backend (the default is 5 if no value is set)

$number = ( ! empty( $instance[‘number’] ) ) ? absint( $instance[‘number’] ) : 5;

if ( ! $number ) {

$number = 5;

}

//limiting excertp length to 10 words

function custom_excerpt_length( $length ) {

return 10;

}

add_filter( ‘excerpt_length’, ‘custom_excerpt_length’, 999 );

//setting up the loop arguments

$args = array(

‘post_type’ => ‘post’,

‘post_status’ => ‘publish’,

‘posts_per_page’ => $number);

$query1 = new WP_Query($args); ?>

<div class=”container-fr”>

<?php /* printing the widget title, if set */

if ( $title ) {

echo ‘<h3 style=”text-align: center;”>’.$args[‘before_title’] . $title . $args[‘after_title’].'</h3>’;} ?>

<?php // The Loop

while ( $query1->have_posts() ) {

$query1->the_post();

$featured_img_url = get_the_post_thumbnail_url();

?>

<!– the widget HTML and PHP –>

<a href=”<?php echo get_permalink(); ?>” >

<div class=”fr-post-container”>

<div class=”fr-thumb” style=”background-image: url(‘<?php echo esc_url($featured_img_url);?>’);”>

</div>

<div class=”fr-text”>

<span style=”margin: 0 0 5px 0; background-color: white; text-align: center; color: #666; display: block;font-weight: bold;”>

<?php

/* truncating the title if it’s more than 20 characters */

$thetitle = get_the_title();

$getlength = strlen($thetitle);

$thelength = 20;

echo substr($thetitle, 0, $thelength);

if ($getlength > $thelength) echo “…”; ?>

</span>

<p><?php the_excerpt(); ?></p>

</div>

</div></a>

<?php } ?>

</div>

<?php

}

 

The admin form – form()

In short, this is the part where we define how the widget will be displayed on the backend, in the ‘Appearances -> Widgets’. Generally, if you are making something very simple, you might just need to create a field where the ‘Title’ for the widget is set. Also, we will create both ‘Title’and ‘Number of posts’ field (which will dictate how many of the recent posts will be displayed). Therefore, this number is actually used in the code above. Also, you will see a variable ‘$number’ which is actually the number we set in the backend. To sum up, this is the code you will need:


public function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
$number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
?>

<p><label for=”<?php echo $this->get_field_id( ‘title’ ); ?>”><?php _e( ‘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>

<p><label for=”<?php echo $this->get_field_id( ‘number’ ); ?>”><?php _e( ‘Number of posts to show:’ ); ?></label>

<input class=”tiny-text” id=”<?php echo $this->get_field_id( ‘number’ ); ?>” name=”<?php echo $this->get_field_name( ‘number’ ); ?>” type=”number” step=”1″ min=”1″ value=”<?php echo $number; ?>” size=”3″ /></p>

<?php

}

}

 

Updating the custom WordPress widget options – update()

So, this part is just what is says – it updates the widget options when you change them in the backend. Also, since I have 2 options in my widget, I will need to set 2 lines for updating them:

 

public function update( $new_instance, $old_instance ) {

$instance = $old_instance;

$instance['title'] = sanitize_text_field( $new_instance['title'] );

$instance['number'] = (int) $new_instance['number'];

}

So, if you have just one option (like widget title) you will need just the first two lines and the title line ( $instance[‘title’] = sanitize_text_field( $new_instance[‘title’] ); ). Additionally, if you have more options, than you will need to specify a line for each of them.

 

Let’s not forget the CSS

So, if you created the CSS file as per instructions above, you can paste the following lines of CSS code to get the styling that I created:

.fr-post-container {width: 235px; padding: 5px; background-color: #eee;margin:auto; min-height: 85px;border-bottom: 1px solid #999; border-radius: 10px; margin-bottom: 5px;transition: all .2s ease-in-out; -webkit-box-shadow: 1px 1px 5px 1px rgba(0,0,0,0.75);

-moz-box-shadow: 1px 1px 5px 1px rgba(0,0,0,0.75);

box-shadow: 1px 1px 5px 1px rgba(0,0,0,0.75);}

.fr-post-container:hover {background-color: #eee; transform: scale(1.1);}

.fr-thumb {float: left; width: 75px; height: 75px; background-size: cover; background-position: center center; display: inline-block; }

.fr-text {width: 150px; display: inline-block; font-size: 11px; padding-left:5px;font-family: ‘Times New Roman’;}

.fr-text p {text-align: justify; margin: 0;background-color: white;padding:5px 5px 0px 5px; color: #666;line-height:11px;}

.container-fr {padding-top:10px; padding-bottom:10px;margin-bottom:20px;}

In short,we will not go into detail what each line of code does. However, they are pretty straight forward and take about 5 minutes to Google out.

 

Testing the widget

Therefore, if you followed the instructions correctly (or exactly, provided you wanted to create an identical widget) you can go ahead and add the widget to your sidebar. Go to ‘Appearance->Widgets’ and add the ‘Fixrunner Custom Widget’ to your sidebar area.

The result should be a widget that displays a post thumbnail, post title and the excerpt with each of the items growing in size when hovered over:

Also, coding the widgets requires some Object-Oriented Programming familiarity and at least some knowledge of the WordPress loop. You should consult the WordPress Codex if you are in doubt, and you will be. There’s nothing wrong or odd about it.

At least, know you know how to set up a plugin/widget directory and file. In short, if this sounds too complicated, you can reach out to us for any WordPress help you might need with your WordPress site. Also, be sure to check out our services.