The WIDGET

The WIDGET will take you through the process of creating a WordPress Widget. Wordpress Widgets are small components built as PHP classes that are added to WordPress sidebars in the Admin Desktop interface. They display on any pages where the sidebar displays. They can also be used in other places on a WordPress page, such as headers, footers, etc.

This project has the following steps:

Project Set-up. You can continue working with the blog project you just created in The BLOG, or you can start a new site. If you start a new site, I recommend naming it n413_widget. The instructions will assume you are using a new project. Set up a new database and do a fresh install of the Wordpress files, as explained in The INSTALL.

Twenty Sixteen. The current versions of WordPress come with themes that do not have sidebars, so we will look for a theme that has at least one sidebar set up as a default. The most recent WordPress standard theme that has a sidebar is Twenty Sixteen, so we will use that one. In the dashboard, go to Appearance>Themes and click the "Add New" button. This will display a large set of themes available for download. Use the Search field and type in "Twenty Sixteen". You will see Twenty Sixteen in the list. Mouse over it and click the "Install" button. Once the download completes, click "Activate". Congratulations, you have installed a new theme. Add a few blog posts if you wish.

Child Theme. Create a new child theme, just as you did for The CHILD. You will need to modify the style sheet header to point to the new theme. The header should look like this:

/*
Theme Name: Twenty Sixteen Child
Theme URI: http://www.example.com/ 
description: >-
  A child theme for Twenty-Sixteen and the N413/AMPJAM Widget Project
Author: <your name>
Author URI: http://example.com
Template: twentysixteen
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: right-sidebar
Text Domain: twenty-sixteen-child
*/
/* Custom CSS goes after this line */            
            

Borrow the index.php file from the twentysixteen theme directory, and create the functions.php file just as you did for The CHILD. In fact, you can copy the functions.php file from that project into this one.

Be sure to activate the child theme in the Wordpress dashboard.

The Widget. You can write the code for a widget in functions.php, but to keep things organized, create a "widgets" directory within your child theme directory, then create a new PHP file named "Hello_world_widget.php" for the widget code. We will use a PHP "include" inside functions.php to pull in the widget code.

Once you have the new widget directory and file in place, add the "include" statement into functions.php, which should now look like this:

<?php
function enqueue_parent_styles(){
    wp_enqueue_style('parent-style', get_template_directory_uri().'/style.css');
}
add_action('wp_enqueue_scripts', 'enqueue_parent_styles');

//include widget class
include("widgets/Hello_world_widget.php");

The Class. Inside the file, create a PHP class:

<?php
class Hello_world_widget extends WP_Widget {

}

WordPress already has a WP_Widget class, so you are extending it with your code. This makes all the standard widget class functions available to you. The class needs four functions:

  • __construct() This sets the widget id, name, and other properties.
  • widget() This contains the widget functionality.
  • form() This provides a way to set widget options in the WP admin dashboard.
  • upload() This provides a way to store the widget options to the database.

Let's put those four functions in place:

<?php
class Hello_world_widget extends WP_Widget {
    
    //constructor function
    public function __construct(){

    }

    //widget functionality
    public function widget($args, $instance){

    }

    //Widget admin dashboard options
    public function form($instance){

    }

    //database updates
    public function update($new_instance, $old_instance){

    }
} //end class Hello_world_widget 

The constructor function will contain a call to the parent class's constructor function, with a few arguments, including an id string, the widget name, and an array with other widget set-up options, such as a description of the widget. Here's what it looks like:

//constructor function
public function __construct(){
    $widget_id = 'hello_world_widget'; //this is a unique identifier string
    $widget_name = 'Hello World Widget'; //this is a label for display
    $widget_options = array('description' => 'This is my first N413 widget. It says "Hello World".');
    parent::__construct($widget_id,$widget_name,$widget_options);
}

You will find examples of the constructor function that are more complicated, but this is the stripped-down version. Some constructor functions include the code for registering the widget, but we will place that in the functions.php file. Also, you will find examples that enclose the name and description in the WordPress '__()' function, which provides the option of translating the title and description into other languages.

Other variations you will find in the widget class code examples include an $args array placed before the widget() function. The widget() function requires an $args array argument to define the HTML string values that format the widget and the title. However, these are usually passed in from the theme or the sidebar where the widget will be displayed, which is what we will assume here.

Let's build the widget() function:

//widget functionality
public function widget($args, $instance){
    echo $args['before_widget'];
    $title = $instance['title'];
    echo $args['before_title'] . $title . $args['after_title'];

    //main body of the widget
    echo '<h2>Hello World!</h2>
          <p>This is my first N413 WordPress widget</p>';

    echo $args['after_widget'];
} //end function widget

This function will check the $args array for HTML formatting (<div> or <h> tags) to place before and after the widget and the title. The title text will come from the $instance array. "Hello World", is the main output of the widget() function. The output can be very complex for a complex widget, but in this simple example, you can clearly see how the widget does its work.

Now build the form() function:

//Widget admin dashboard options
public function form($instance){
    if(isset($instance["title"])){
        $title = $instance["title"];
    }else{
        $title = "Hello World Widget";
    }
    //widget admin dashboard form
    echo '
    <p>
    <label for="'.$this->get_field_id( 'title' ).'">Title:</label>
    <input class="widefat" id="'.$this->get_field_id( 'title' ).'" name="'.$this->get_field_name( 'title' ).'" type="text" value="'.esc_attr( $title ).'"/>
    </p>';
}//end function form

The form() function will check to see if the instance has a title, and if not, creates a default title. It then defines the HTML for a form input to be used in the admin dashboard. In this simple version, the form simply allows the user to change the title of the widget.

The last required function for the widget is the update() function. This allows changes to the widget's options to be stored in the wp_options table:

                   
//database updates
public function update($new_instance, $old_instance){
    $instance = array();
    $title = '';
    if(! empty($new_instance["title"])){ $title = strip_tags($new_instance["title"]); }
    $instance["title"] = $title;
    return $instance;
}//end update function

The update() function requires the $new_instance and $old_instance arguments. The purpose of the function is to return a complete version of the widget instance, and with a more complex widget, the $old_instance values will be updated with the $new_instance values to create the $instance array returned from the function.

We now have a complete Widget class:

<?php
class Hello_world_widget extends WP_Widget {
    
//constructor function
public function __construct(){
    $widget_id = 'hello_world_widget'; //this is a unique identifier string
    $widget_name = 'Hello World Widget'; //this is a label for display
    $widget_options = array('description' => 'This is my first widget. It says "Hello World".');
    parent::__construct($widget_id,$widget_name,$widget_options);
}

//widget functionality
public function widget($args, $instance){
    echo $args['before_widget'];
    $title = $instance['title'];
    echo $args['before_title'] . $title . $args['after_title'];

    //main body of the widget
    echo '<h2>Hello World!</h2>
          <p>This is my first N413 WordPress widget</p>';

    echo $args['after_widget'];
} //end function widget

//Widget admin dashboard options
public function form($instance){
    if(isset($instance["title"])){
        $title = $instance["title"];
    }else{
        $title = "Hello World Widget";
    }
    //widget admin dashboard form
    echo '
    <p>
    <label for="'.$this->get_field_id( 'title' ).'">Title:</label>
    <input class="widefat" id="'.$this->get_field_id( 'title' ).'" name="'.$this->get_field_name( 'title' ).'" type="text" value="'.esc_attr( $title ).'"/>
    </p>';
}//end function form

//database updates
public function update($new_instance, $old_instance){
    $instance = array();
    $title = '';
    if(! empty($new_instance["title"])){ $title = strip_tags($new_instance["title"]); }
    $instance["title"] = $title;
    return $instance;
}//end update function

} //end class Hello_world_widget

Register. The next step is to include your widget class in the functions.php file and register the widget. Start with the child-theme functions.php file as shown above, create a function to register the widget, then add an "action" to call the register function:

<?php
function enqueue_parent_styles(){
    wp_enqueue_style('parent-style', get_template_directory_uri().'/style.css');
}
add_action('wp_enqueue_scripts', 'enqueue_parent_styles');

//include widget class
include("widgets/Hello_world_widget.php");

//Register the widget
function register_hello_world(){
    register_widget('hello_world_widget');
}
add_action('widgets_init', 'register_hello_world'); 

The register_widget() function will take the widget's id as an argument. Registering the widget makes it appear in the admin dashboard inside the Appearance>Widgets section. From there, you can drag the widget into a sidebar, where it will display.

Give it a try. You should see a widget with the "Hello World Widget" title, which you can drag into the theme's sidebar. When you view a page that uses the sidebar, you will see the widget as part of the sidebar. If you don't see the widget in the widget list, check to be sure you activated the child theme.

Congratulations! You have built a WordPress Widget!

To take things further, build your own widget that has more functionality. A few Google searches will turn up resources for building widgets that display recently viewed posts, frequently viewed posts, or any number of other things you might want to show in a WordPress sidebar. And don't forget "sidebars" can be displayed in many locations of the page, such as the footer, etc.

There are many good resources online that explain how to create widgets in more detail. Here are a few:
https://www.wpbeginner.com/wp-tutorials/how-to-create-a-custom-wordpress-widget/
https://developer.wordpress.org/themes/functionality/widgets/
https://kinsta.com/blog/wordpress-widgets/