A Full WordPress Plugin Example — Part 3 Widget

A widget is a PHP object that outputs some HTML such as a calender widget. In this part, we will add our own widget for the plugin GCMovie created in part 1.

We add a new file named class-gcmovie-widget.php under the plugin’s inc folder. Now the plugin folder structure looks like this:

gcmovie/        // The plugin folder
    gcmoive.php // The main plugin file
    inc/
        class-gcmovie-shortcode.php  // Shortcode
        class-gcmovie-widget.php     // Widget
    assets/     // Resoure folder        
        css/
            gcmovie-admin.css  // Styles for admin pages
            gcmovie-puglic.css // Styles for public pages

Create Our Widget Class

Add below code to class-gcmovie-shortcode.php file.

<?php
/*
 * Widget for GCMovie
 */

if ( ! defined( 'WPINC' ) ) {
    die( 'No direct access.' );
}

class GCMovie_Widget extends WP_Widget {
}

We need to extend the standard WP_Widget class and some of its functions.

Next we will override some extended functions from WP_Widget inside GCMovie_Widget.

Register a Widget

In the construct function, we first call the parent’s construct function to set the widget’s information, and then register our widget using the widgets_init hook.

    function __construct() {
        parent::__construct(
            'gcmovie_widget', // Base ID
            'GCMovie Widget', // Name
            array( 'description' => 'Display movies' )
        );

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

Here we define the callback just in place. register_widget() is used to register a widget.

Widget Settings in Back-end: form()

When adding a widget to some area, it normally comprises two areas (title area and options area) that can be used to customize its settings. Our movie widget will automatically get title through the post ID, therefor the tile is ignored.

Our movie widget allows to set the below two values:

  • id, the movie post ID.
  • show_thumbnail, whether to display the movie tailer.

You may noticed that the parameters of our widget are the same as our shortcode in Part 2. That simplifies our code via reusing the function displaying a shortcode.

WP_Widget::form is used to output the settings form of a widget when it is added to some widget area.

    /**
     * Handler for widget options settings
     */
    function form( $instance ) {
        $id = isset( $instance['id'] ) ? $instance['id'] : 0;
        $show_thumbnail = isset( $instance['show_thumbnail'] ) ? $instance['show_thumbnail'] : true ;

        ?>
        <p>Movie Options</p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_name( 'id' ) ); ?>">Movies</label>
            <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'id' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>" value="<?php echo $id; ?>">">
                <?php
                $args = array(
                    'posts_per_page'    => -1,
                    'post_type'         => 'gcmovie'
                );
                $posts = get_posts( $args );
                if ( $posts ) {
                    foreach ( $posts as $p ) {
                        if ( $p->ID == $id ) {
                            echo '<option selected value="' . $p->ID . '">' . get_the_title( $p->ID ) . '</option>';
                        } else {
                            echo '<option value="' . $p->ID . '">' . get_the_title( $p->ID ) . '</option>';
                        }
                    }
                }
                ?>
            </select>
        </p>
        <p>
            <input class="widefat" type="checkbox" id="<?php echo esc_attr( $this->get_field_id( 'show_thumbnail' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'show_thumbnail' ) ); ?>" value="show" checked="<?php echo $show_thumbnail ? 'true' : 'false'; ?>">
            <label for="<?php echo esc_attr( $this->get_field_id( 'show_thumbnail' ) ); ?>" >Show thumnail</label>
        </p>
        <?php
    }

It takes one parameter instance which contains current settings. Inside the function, we first set the default values if the instance hasn’t been saved before. Then we display a movie list from which the user selects one to be displayed inside the widget and a checkbox to set whether to display the movie trailer.

In the process, you have to set the id attribute for each field through WP_Widget::get_field_id(). It is used to construct id attributes for use in WP_Widget::form() fields. Otherwrise, WordPress will not be able to save that field for us.

Widget Settings Checking before Saving: update()

WP_Widget::update() is used to check the settings before the widget is saved, for example you can make some sanitizing operations (See more on Securing Input) to secure the input.

    /**
     * Handler for widget options saving
     */
    function update( $new_instance, $old_instance ) {
        $instance = array();

        $instance['id'] = $new_instance['id'];
        $instance['show_thumbnail'] = isset( $new_instance['show_thumbnail'] ) ? true : false;

        return $instance;
    }

It takes two parameters:

  • new_instance (array) (Required) Put the newly-calculated values to $new_instance.
  • old_instance — (array) (Required) Check old values in $old_instance.

Widget Front-end Display Function: widget()

Override WP_Widget::widget() which is used to display a widget in the front-end.

    /**
     * Handle for widget display
     * $args, set by the widget area
     * $instance, saved values
     */
    function widget( $args, $instance ) {
        echo $args['before_widget'];

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

        echo GCMovie_Shortcode::parse_shortcode( $instance );

        echo $args['after_widget'];
    }

It takes two parameters:

  • args — (array) (Required) It contaIns display arguments like before_title, after_title, before_widget and after_widget.
  • instance — (array) (Required) It contains the settings for the particular instance of the widget.

Here we reuse the function parse_shortcode that is defined in Part 2 for our shortcode to display a widget in the front-end.

Initiate a Widget Instance

Inside GCMovie_Widget, define a static function to initiate a widget instance.

    static function init() {
        new GCMovie_Widget;
    }

Call init() outside the class GCMovie_Widget.

class GCMovie_Widget extends WP_Widget {
    //...
}

GCMovie_Widget::init();

Include Widget File in Plugin Main File

Add below code to the bottom of gcmovie.php to make the code take effect.

require_once GCMOVIE_PLUGIN_DIR . 'inc/class-gcmovie-widget.php';

gcmovie.php now look like:

//...
GCMovie::init();
require_once GCMOVIE_PLUGIN_DIR . 'inc/class-gcmovie-shortcode.php';
require_once GCMOVIE_PLUGIN_DIR . 'inc/class-gcmovie-widget.php';

Our widget will appear in the user’s Administration Screens at Appearance > Widgets. You can add the widget to the sidebar area and customize the widget settings as below.

GCMovie Widget in Widgets Page

Below is a widget added to the sidebar.

GCMovie Widget

Resources

Leave a Reply