1

Trying to figure out the proper way of creating a very simple (reusable) WordPress Widget. Found this article by wpbeginner that seems to be the most comprehensive: https://www.wpbeginner.com/wp-tutorials/how-to-create-a-custom-wordpress-widget/

// Creating the widget 
class wpb_widget extends WP_Widget {

function __construct() {
parent::__construct(
// Base ID of your widget
'wpb_widget', 

// Widget name will appear in UI
__('WPBeginner Widget', 'wpb_widget_domain'), 

// Widget description
array( 'description' => __( 'Sample widget based on WPBeginner Tutorial', 'wpb_widget_domain' ), ) 
);
}

// Creating widget front-end
// This is where the action happens
public function widget( $args, $instance ) {
$title = apply_filters( 'widget_title', $instance['title'] );
// before and after widget arguments are defined by themes
echo $args['before_widget'];
if ( ! empty( $title ) )
echo $args['before_title'] . $title . $args['after_title'];

// This is where you run the code and display the output
echo __( 'Hello, World!', 'wpb_widget_domain' );
echo $args['after_widget'];
}

// Widget Backend 
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'New title', 'wpb_widget_domain' );
}
// Widget admin form
?>
<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 esc_attr( $title ); ?>" />
</p>
<?php 
}

// Updating widget replacing old instances with new
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
return $instance;
}
} // Class wpb_widget ends here

// Register and load the widget
function wpb_load_widget() {
    register_widget( 'wpb_widget' );
}
add_action( 'widgets_init', 'wpb_load_widget' );

My question, how to include two widget options and their admin-form values (ex. custom number/text and it's font color) in the most proper way?

2 Answers 2

7

To have multiple options, update 3 sections from your above code 1) The front end

public function widget( $args, $instance ) {
//store the options in variables
$option1 = $instance['option1'];
$option2 = $instance['option2'];

// before widget (defined by theme)
echo $args['before_widget'];

//use your options 
//(e.g. a paragraph with option1 as the text and option2 as its class for CSS)
//don't forget error/empty content handling/filters
echo "<p class='" . $option2 . "'>" . $option1 . "</p>";

// after widget (defined by theme)
echo $args['after_widget'];
}

2) The Backend w/ Form

//
public function form( $instance ) {
    //Check if option1 exists, if its null, put "new option1" for use in the form
    if ( isset( $instance[ 'option1' ] ) ) {
        $option1 = $instance[ 'option1' ];
    }
    else {
        $option1 = __( 'new option1', 'wpb_widget_domain' );
    }
    //Repeat for option2
    if ( isset( $instance[ 'option2' ] ) ) {
        $option1 = $instance[ 'option2' ];
    }
    else {
        $option1 = __( 'new option2', 'wpb_widget_domain' );
    }
<p>
<label for="<?php echo $this->get_field_id( 'option1' ); ?>"><?php _e( 'Option1:' ); ?</label> 
<input class="widefat" id="<?php echo $this->get_field_id( 'option1' ); ?>" name="<?php echo $this->get_field_name( 'option1' ); ?>" type="text" value="<?php echo esc_attr( $option1 ); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'option2' ); ?>"><?php _e( 'Option2:' ); ?</label> 
<input class="widefat" id="<?php echo $this->get_field_id( 'option2' ); ?>" name="<?php echo $this->get_field_name( 'option2' ); ?>" type="text" value="<?php echo esc_attr( $option2 ); ?>" />
</p>

3) The function that saves your new widget settings

public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['option1'] = ( ! empty( $new_instance['option1'] ) ) ? strip_tags( $new_instance['option1'] ) : '';
$instance['option2'] = ( ! empty( $new_instance['option2'] ) ) ? strip_tags( $new_instance['option2'] ) : '';
return $instance;
}

Essentially, you just have to repeat the right things and make sure you hit all the 3 key areas. Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the complete explanation seems obvious for some but actually helps a lot in understanding!
0

It is simple method to create custom widget in wordpress. This is widget for commemted post.

    <?php

    // Creating the widget 
    class commented_news_sidebar extends WP_Widget {

        function __construct() {
        parent::__construct(
        // Base ID of your widget
        'commented_news_sidebar', 

        // Widget name will appear in UI
        __('Commented News Widget', 'wpb_widget_domain'), 

        // Widget description
        array( 'description' => __( 'Your site&#8217;s Most Commented News.', 'wpb_widget_domain' ), ) 
        );
        }

        // Creating widget front-end
        // This is where the action happens
        public function widget( $args, $instance ) {

            if ( ! isset( $args['widget_id'] ) ) {
                $args['widget_id'] = $this->id;
            }

        /*$the_query = new WP_Query(array(  'orderby' => 'comment_count', 'order'=> 'DESC' ));*/

            $commentpost = new WP_Query( apply_filters( 'widget_posts_args', array(
                'cat' => $instance['showcommentedcat'],
                'orderby' => 'comment_count', 
                'posts_per_page' => 3,
                'order' => 'DESC',
    /*          'post_status' => 'publish', 
                */

            ) ) );


            if ($commentpost->have_posts()) :
            ?>

                <div class="nav-box"> <h4><?php echo $instance['title'];?></h4></h4></div><!-- nav-box -->

                <?php 

                $postthumb_id = null;
                $con = null;
                $img_url = null;

                while ( $commentpost->have_posts() ) : $commentpost->the_post();
                   ?>
                  <?php
                    $postthumb_id = get_post_thumbnail_id( get_the_ID());
                    $con = get_the_content($postthumb_id);
    /*
                    $comments_count = wp_count_comments(get_the_ID());
                    print_r($comments_count);
                    */
                    $img_url = wp_get_attachment_image_src( $postthumb_id , 'most-comment-img-size');
                  ?>
                    <div class="comm-most"><!-- comm-most -->
                    <?php $commented_cat_nm = get_cat_name($instance['showcommentedcat']);?>
                    <a href="<?php the_permalink(); ?>">
                        <img src="<?php echo $img_url[0]; ?>" alt="">
                        <span><?php echo $commented_cat_nm; ?></span>
                        <p><?php get_the_title() ? the_title() : the_ID(); ?></p>
                    </a>

                    </div><!-- comm-most -->

                <?php endwhile; ?>

                <?php
                // Reset the global $the_post as this query will have stomped on it
                wp_reset_postdata();

            endif;


        }


        // Widget Backend 
        public function form( $instance ) {
            if ( isset( $instance[ 'title' ] ) ) {
                $title = $instance[ 'title' ];
            }
            else {
                $title = __( 'New title', 'wpb_widget_domain' );
            }

            $oldcat =  $instance['showcommentedcat'];
            // Widget admin form
    ?>
          <?php
                $categories = get_categories( array(
                    'orderby' => 'name',
                ) );
            ?>

            <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 esc_attr( $title ); ?>" />
            <br>

            <label for="<?php echo $this->get_field_id( 'showcommentedcat' ); ?>"><?php _e( 'Category:' ); ?></label> 
            <select id="<?php echo $this->get_field_id('showcommentedcat'); ?>" name="<?php echo $this->get_field_name('showcommentedcat'); ?>" class="widefat" >
                <?php foreach ( $categories as $category ) {?>
                        <option <?php selected($instance['showcommentedcat'], esc_html( $category->name ));?> value="<?php echo $category->term_id ; ?>" <?php if($oldcat == $category->term_id){echo "selected";}?>><?php echo $category->name ; ?> </option>
                <?php } ?>
            </select>

            </p>
        <?php 
        }


        // Updating widget replacing old instances with new
        public function update( $new_instance, $old_instance ) {
            $instance = array();
            $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
            $instance['showcommentedcat'] = $new_instance['showcommentedcat'];
            return $instance;
        }
    } // Class commented_news_sidebar ends here


    // Register and load the widget
    function wpb_load_widget_commented_news() {
        register_widget( 'commented_news_sidebar' );
    }

    add_action( 'widgets_init', 'wpb_load_widget_commented_news' );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.