widget() method can't access $instance variable WordPress - php

I followed a guide to create a WordPress plugin, which shows a youtube sub button on your page.
In the guide it works perfectly, but for some reason it doesn't work for me.
This is my problem:
When I var_dump($instance) in widget() it prints out an empty array, but when I try to print_r($instance) inside of my form() it prints out the correct information
Here is the widget file:
<?php
/**
* Adds Youtube_Subs widget.
*/
class Youtube_Subs_Widget extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'youtubesubs_widget', // Base ID
esc_html__( 'YouTube Subs', 'mp_domain' ), // Name
array( 'description' => esc_html__( 'Widget to display YouTube subs', 'mp_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 ) {
echo $args['before_widget']; // Whatever you want to display before widget (<div>, etc)
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
}
// Widget Content Output
var_dump($instance);
// echo '<div class="g-ytsubscribe" data-channel="'.$instance['channel'].'" data-layout="'.$instance['layout'].'" data-count="'.$instance['count'].'"></div>';
echo $args['after_widget']; // Whatever you want to display after widget (</div>, etc)
}
/**
* 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_attr( 'YouTube Subs', 'mp_domain' ));
$channel = (! empty( $instance['channel'] ) ? $instance['channel'] : esc_attr( 'techguyweb', 'mp_domain' ));
$layout = (! empty( $instance['layout'] ) ? $instance['layout'] : esc_attr( 'default', 'mp_domain' ));
$count = (! empty( $instance['count'] ) ? $instance['count'] : esc_attr( 'default', 'mp_domain' ));
?>
<!-- TITLE -->
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
<?php esc_attr_e( 'Title:', 'mp_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 ); ?>">
</p>
<!-- CHANNEL -->
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'channel' ) ); ?>">
<?php esc_attr_e( 'Channel:', 'mp_domain' ); ?>
</label>
<input
class="widefat"
id="<?php echo esc_attr( $this->get_field_id( 'channel' ) ); ?>"
name="<?php echo esc_attr( $this->get_field_name( 'channel' ) ); ?>"
type="text"
value="<?php echo esc_attr( $channel ); ?>">
</p>
<!-- LAYOUT -->
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'layout' ) ); ?>">
<?php esc_attr_e( 'Layout:', 'mp_domain' ); ?>
</label>
<select
class="widefat"
id="<?php echo esc_attr( $this->get_field_id( 'layout' ) ); ?>"
name="<?php echo esc_attr( $this->get_field_name( 'layout' ) ); ?>">
<option value="default" <?php echo ($layout == 'default') ? 'selected' : ''; ?>>
Default
</option>
<option value="full" <?php echo ($layout == 'full') ? 'selected' : ''; ?>>
Full
</option>
</select>
</p>
<!-- COUNT -->
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>">
<?php esc_attr_e( 'Count:', 'mp_domain' ); ?>
</label>
<select
class="widefat"
id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"
name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>">
<option value="default" <?php echo ($count == 'default') ? 'selected' : ''; ?>>
Default
</option>
<option value="hidden" <?php echo ($count == 'hidden') ? 'selected' : ''; ?>>
Hidden
</option>
</select>
</p>
<?php
print_r($instance);
}
/**
* 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 = $old_instance;
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
$instance['channel'] = ( ! empty( $new_instance['channel'] ) ) ? strip_tags( $new_instance['channel'] ) : '';
$instance['layout'] = ( ! empty( $new_instance['layout'] ) ) ? strip_tags( $new_instance['layout'] ) : '';
$instance['count'] = ( ! empty( $new_instance['count'] ) ) ? strip_tags( $new_instance['count'] ) : '';
return $instance;
}
}
I have this hooked up with my plugin file in where I register the widget:
// Register Widget
function register_myplugin() {
register_widget('Youtube_Subs_Widget');
}
// Hook in function
add_action('widgets_init', 'register_myplugin');
I hope someone knows what is wrong and can help me correct my mistake, thanks in advance

I tried to reinstall my WordPress file and it worked afterwards

Related

Some problems in custom widget

I made a custom widget for my template, which has an image upload section
For the first time, I upload an image, it displays correctly, without any problem, but when I want to change the image, it does not change, it displays the same image as before, that part of the image cannot be updated.
Thank you for your guidance
code PHP
<?php
class widget_author extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'author', // Base ID
esc_html__( 'widget_test', 'text_domain' ), // Name
array( 'description' => esc_html__( 'widget test', 'text_domain' ), ) // Args
);
}
/**
* Front-end display of the widget.
*
* #param array $args Widget arguments.
* #param array $instance Saved values from the database.
*
* #see WP_Widget::widget()
*
*/
public function widget( $args, $instance ) {
$upload_image = strip_tags($instance['upload_image']);
echo $args['before_widget'];
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
} ?>
<div class="thumb">
<?php
if ( ! empty( $instance['upload_image'] ) ) { ?>
<img src="<?php echo $upload_image; ?>"></a>
<?php } ?>
</div>
<?php
echo $args['after_widget'];
}
/**
* Back-end widget form.
*
* #param array $instance Previously saved values from the database.
*
* #see WP_Widget::form()
*
*/
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : '';
$upload_image = ! empty( $instance['upload_image'] ) ? $instance['upload_image'] : '';
?>
<!-- Title -->
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
<?php esc_attr_e( 'Widget 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 ); ?>">
</p>
<!-- Upload Image -->
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'upload_image' ) ); ?>">
<?php esc_attr_e( 'Image:', 'text_domain' ); ?>
</label>
<img class="<?= $this->id ?>_img" src="<?= (!empty($instance['upload_image'])) ? $instance['upload_image'] : ''; ?>" style="margin:0;padding:0;max-width:100%;display:block"/>
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'upload_image' ) ); ?>"
name="<?php echo esc_attr( $this->get_field_name( 'upload_image' ) ); ?>" type="text"
value="<?= $instance['upload_image'] ?? ''; ?>">
<button id="<?= $this->id ?>" class="upload_image_button button button-primary" style="margin-top: 5px;">Upload Image</button>
</p>
<?php
}
/**
* Sanitize widget form values as they are saved.
*
* #param array $new_instance Values just sent to be saved.
* #param array $old_instance Previously saved values from the database.
*
* #return array Updated safe values to be saved.
* #see WP_Widget::update()
*
*/
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
$instance['upload_image'] = ( ! empty( $new_instance['upload_image'] ) ) ? sanitize_text_field( $new_instance['upload_image'] ) : '';
return $instance;
}
}
code java
jQuery(document).ready(function ($) {
$(document).on("click", ".upload_image_button", function (e) {
e.preventDefault();
var $button = $(this);
// Create the media frame.
var file_frame = wp.media.frames.file_frame = wp.media({
title: 'Select or upload image',
library: { // remove these to show all
type: 'image' // specific mime
},
button: {
text: 'Select'
},
multiple: false // Set to true to allow multiple files to be selected
});
// When an image is selected, run a callback.
file_frame.on('select', function () {
// We set multiple to false so only get one image from the uploader
var attachment = file_frame.state().get('selection').first().toJSON();
$button.siblings('input').val(attachment.url);
});
// Finally, open the modal
file_frame.open();
});
});

Widget options displayed under widget

I made my first Wordpress widget today and everything works as it is supposed to on my local Wordpress installation(same version as on server). But now I uploaded it to my server and the options of the widget are displayed under the widget on the page instead of the widget option place on the admin side and I can't figure out why.
Here is the code:
// 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
__('Taxi prijs calculator', 'wpb_widget_domain'),
// Widget description
array( 'description' => __( 'Taxi prijs calculator', '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'] );
$shadow = $instance['shadow'];
$maincolor = $instance['maincolor'];
$textcolor = $instance['textcolor'];
$shadowcolor = $instance['shadowcolor'];
// before and after widget arguments are defined by themes
echo $args['before_widget'];
if ( ! empty( $title ) )
echo $args['before_title'] . $title . $args['after_title'];
//Here is my code for the widget took it out to save space.
echo $args['after_widget'];
}
// Widget Backend
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'New title', 'wpb_widget_domain' );
}
if ( isset( $instance[ 'shadow' ] ) ) {
$shadow = $instance[ 'shadow' ];
}
else {
$shadow = __( 'new shadow', 'wpb_widget_domain' );
}
if ( isset( $instance[ 'maincolor' ] ) ) {
$maincolor = $instance[ 'maincolor' ];
}
else {
$maincolor = __( 'new maincolor', 'wpb_widget_domain' );
}
if ( isset( $instance[ 'textcolor' ] ) ) {
$textcolor = $instance[ 'textcolor' ];
}
else {
$textcolor = __( 'new textcolor', 'wpb_widget_domain' );
}
if ( isset( $instance[ 'shadowcolor' ] ) ) {
$shadowcolor = $instance[ 'shadowcolor' ];
}
else {
$shadowcolor = __( 'new shadowcolor', '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>
<p>
<label for="<?php echo $this->get_field_id( 'shadow' ); ?>"><?php _e( 'Display shadow:' ); ?></label> <br>
<input type="radio" id="<?php echo $this->get_field_id( 'shadow' ); ?>" name="<?php echo $this->get_field_name( 'shadow' ); ?>" value="yes" <?php if($shadow == "yes" || $shadow = "new shadow"){ echo "checked";}?>>Yes <input type="radio" id="<?php echo $this->get_field_id( 'shadow' ); ?>" name="<?php echo $this->get_field_name( 'shadow' ); ?>" value="no" <?php if($shadow == "no"){ echo "checked";}?>>No
</p>
<p>
<label for="<?php echo $this->get_field_id( 'shadowcolor' ); ?>"><?php _e( 'Shadow color:' ); ?></label><br>
<input type="color" id="<?php echo $this->get_field_id( 'shadowcolor' ); ?>" name="<?php echo $this->get_field_name( 'shadowcolor' ); ?>" value="<?php if(empty($shadowcolor) || $shadowcolor == "new shadowcolor") { echo "#323232";}else{echo esc_attr( $shadowcolor );} ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id( 'maincolor' ); ?>"><?php _e( 'Main color:' ); ?></label><br>
<input type="color" id="<?php echo $this->get_field_id( 'maincolor' ); ?>" name="<?php echo $this->get_field_name( 'maincolor' ); ?>" value="<?php if(empty($maincolor) || $maincolor == "new maincolor") { echo "#FDD017";}else{echo esc_attr( $maincolor );} ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id( 'textcolor' ); ?>"><?php _e( 'Text color:' ); ?></label><br>
<input type="color" id="<?php echo $this->get_field_id( 'textcolor' ); ?>" name="<?php echo $this->get_field_name( 'textcolor' ); ?>" value="<?php if(empty($textcolor) || $textcolor == "new textcolor") { echo "#000000";}else{echo esc_attr( $textcolor );} ?>">
</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['shadow'] = ( ! empty( $new_instance['shadow'] ) ) ? strip_tags( $new_instance['shadow'] ) : '';
$instance['maincolor'] = ( ! empty( $new_instance['maincolor'] ) ) ? strip_tags( $new_instance['maincolor'] ) : '';
$instance['textcolor'] = ( ! empty( $new_instance['textcolor'] ) ) ? strip_tags( $new_instance['textcolor'] ) : '';
$instance['shadowcolor'] = ( ! empty( $new_instance['shadowcolor'] ) ) ? strip_tags( $new_instance['shadowcolor'] ) : '';
return $instance;
}
} // Class wpb_widget ends here
// Register and load the widget
function wpb_load_widget() {
register_widget( 'wpb_widget' );
}
function prefix_add_my_stylesheet() {
// Respects SSL, Style.css is relative to the current file
wp_register_style( 'prefix-style', plugins_url('css/taxi.css', __FILE__) );
wp_enqueue_style( 'prefix-style' );
}
add_action( 'wp_enqueue_scripts', 'prefix_add_my_stylesheet' );
add_action( 'widgets_init', 'wpb_load_widget' );
This is what happens:

How to create a custom WordPress widget with widget options

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: http://goo.gl/7O8Izg
// 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?
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.
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’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' );

How to add another text box to WP_Widget_Text

I am new to wordpress and widgets.
I am trying to add another field to the default text widget. Can you guys help me out.
An image of what i am trying to do:
http://imgur.com/KoYvV
I was able to edit default-widgets.php and add another textarea but it does not work properly. please help and guide me to the right direction.
class WP_Widget_Text extends WP_Widget {
function __construct() {
$widget_ops = array('classname' => 'widget_text', 'description' => __('Arbitrary text or HTML'));
$control_ops = array('width' => 400, 'height' => 350);
parent::__construct('text', __('Text'), $widget_ops, $control_ops);
}
function widget( $args, $instance ) {
extract($args);
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
$text = apply_filters( 'widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance );
$text = apply_filters( 'widget_text2', empty( $instance['text2'] ) ? '' : $instance['text2'], $instance );
echo $before_widget;
if ( !empty( $title ) ) { echo $before_title . $title . $after_title; } ?>
<div class="textwidget">
<?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?>
</div>
<div class="textwidget2">
<?php echo !empty( $instance['filter'] ) ? wpautop( $text2 ) : $text2; ?>
</div>
<?php
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
if ( current_user_can('unfiltered_html') ) {
$instance['text'] = $new_instance['text'];
$instance['text2'] = $new_instance['text2'];
} else {
$instance['text'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text']) ) ); // wp_filter_post_kses() expects slashed
$instance['text2'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text2']) ) ); // wp_filter_post_kses() expects slashed
}
$instance['filter'] = isset($new_instance['filter']);
return $instance;
}
function form( $instance ) {
$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '', 'text2' => '' ) );
$title = strip_tags($instance['title']);
$text = esc_textarea($instance['text']);
$text2 = esc_textarea($instance['text2']);
?>
<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>
<textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo $text; ?></textarea>
<textarea class="widefat" rows="8" cols="20" id="<?php echo $this->get_field_id('text2'); ?>" name="<?php echo $this->get_field_name('text2'); ?>"><?php echo $text2; ?></textarea>
<p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox" <?php checked(isset($instance['filter']) ? $instance['filter'] : 0); ?> /> <label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p>
<?php
}
}
I'm not sure if you figured out yet, but here is a solution to your problem.
The first thing is you don't want to edit the widget directly. If you update Wordpress, your code will be overwritten. Wordpress is highly extensible, so you never have to edit the code directly.
Ideally, you should create a plugin. If you want to learn how, read this http://codex.wordpress.org/Writing_a_Plugin
Another great thing about Wordpress is that they have very good documentation.
However, for simplicity we will just do this in functions.php in the theme you are using. You can find it in /wp-content/themes/your_theme/functions.php
Here is the modified version of the code sample in your question:
//First we need to change the name of the Widget. I just named it RT_Widget_Text, so just be aware that you can change it to anything you want and to replace all instances of that text. Just make sure to not name it WP_Widget_Text
class RT_Widget_Text extends WP_Widget {
function __construct() {
//I made a change here. I changed the class name to widget_double_text. This probably has no effect, but I just changed it for good measure.
$widget_ops = array('classname' => 'widget_double_text', 'description' => __('Arbitrary text or HTML'));
$control_ops = array('width' => 400, 'height' => 350);
//Here is the important part. Change the "text" to "double_text" and "Text" to "Text 2" or to some other text that will identify the widget.
parent::__construct('double_text', __('Text 2'), $widget_ops, $control_ops);
}
function widget( $args, $instance ) {
extract($args);
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
$text = apply_filters( 'widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance );
//I changed this to $text2 = instead of $text =
//This would have caused the first text section to display you text2 and your text2 to display nothing.
//I wonder if this was your issue?
$text2 = apply_filters( 'widget_text', empty( $instance['text2'] ) ? '' : $instance['text2'], $instance );
echo $before_widget;
if ( !empty( $title ) ) { echo $before_title . $title . $after_title; } ?>
<div class="textwidget">
<?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?>
</div>
<div class="textwidget2">
<?php echo !empty( $instance['filter'] ) ? wpautop( $text2 ) : $text2; ?>
</div>
<?php
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
if ( current_user_can('unfiltered_html') ) {
$instance['text'] = $new_instance['text'];
$instance['text2'] = $new_instance['text2'];
} else {
$instance['text'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text']) ) ); // wp_filter_post_kses() expects slashed
$instance['text2'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text2']) ) ); // wp_filter_post_kses() expects slashed
}
$instance['filter'] = isset($new_instance['filter']);
return $instance;
}
function form( $instance ) {
$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '', 'text2' => '' ) );
$title = strip_tags($instance['title']);
$text = esc_textarea($instance['text']);
$text2 = esc_textarea($instance['text2']);
?>
<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>
<textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo $text; ?></textarea>
<textarea class="widefat" rows="8" cols="20" id="<?php echo $this->get_field_id('text2'); ?>" name="<?php echo $this->get_field_name('text2'); ?>"><?php echo $text2; ?></textarea>
<p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox" <?php checked(isset($instance['filter']) ? $instance['filter'] : 0); ?> /> <label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p>
<?php
}
}
//Now you need to register your widget. Remember to change it to whatever you named your widget
add_action( 'widgets_init', create_function( '', 'register_widget( "RT_Widget_Text" );' ) );
With all that said, I think your bug may have been a simple typo in your widget( $args, instance) method here:
$text = apply_filters( 'widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance );
$text = apply_filters( 'widget_text2', empty( $instance['text2'] ) ? '' : $instance['text2'], $instance );
Notice that you are setting $text = twice here. So you basically overwrote the value of text and replaced it with text2. And then that left text2 null.
If that was not your problem, then it may have to do with registering the widget as "text" since that is taken by WP_Widget_Text. This is unlikely since I'm assuming you edited the WP_Widget_Text class directly.

Creating a custom categories widget

The code below is an attempt to take the WP_Widget_Categories class and use it as the basis for a custom categories widget based on the default categories widget.
I'm getting no output however and the widget is not showing up in the "Available Widgets" listing. What am I doing wrong?
<?php
/*
Plugin Name: My Categories Widget
Version: 1.0
*/
class MY_Widget_Categories extends WP_Widget {
function MY_Widget_Categories() {
$widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "A list or dropdown of categories" ) );
$this->WP_Widget('categories', __('Categories'), $widget_ops);
}
function widget( $args, $instance ) {
extract( $args );
$title = apply_filters('widget_title', empty( $instance['title'] ) ? __( 'Categories' ) : $instance['title']);
$c = $instance['count'] ? '1' : '0';
$h = $instance['hierarchical'] ? '1' : '0';
$d = $instance['dropdown'] ? '1' : '0';
echo $before_widget;
if ( $title )
echo $before_title . $title . $after_title;
$cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h);
if ( $d ) {
$cat_args['show_option_none'] = __('Select Category');
wp_dropdown_categories(apply_filters('widget_categories_dropdown_args', $cat_args));
?>
<script type='text/javascript'>
/* <![CDATA[ */
var dropdown = document.getElementById("cat");
function onCatChange() {
if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
location.href = "<?php echo get_option('home'); ?>/?cat="+dropdown.options[dropdown.selectedIndex].value;
}
}
dropdown.onchange = onCatChange;
/* ]]> */
</script>
<?php
} else {
?>
<ul>
<?php
$cat_args['title_li'] = '';
wp_list_categories(apply_filters('widget_categories_args', $cat_args));
?>
</ul>
<?php
}
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['count'] = $new_instance['count'] ? 1 : 0;
$instance['hierarchical'] = $new_instance['hierarchical'] ? 1 : 0;
$instance['dropdown'] = $new_instance['dropdown'] ? 1 : 0;
return $instance;
}
function form( $instance ) {
//Defaults
$instance = wp_parse_args( (array) $instance, array( 'title' => '') );
$title = esc_attr( $instance['title'] );
$count = isset($instance['count']) ? (bool) $instance['count'] :false;
$hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
$dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
?>
<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><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('dropdown'); ?>" name="<?php echo $this->get_field_name('dropdown'); ?>"<?php checked( $dropdown ); ?> />
<label for="<?php echo $this->get_field_id('dropdown'); ?>"><?php _e( 'Show as dropdown' ); ?></label><br />
<input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>"<?php checked( $count ); ?> />
<label for="<?php echo $this->get_field_id('count'); ?>"><?php _e( 'Show post counts' ); ?></label><br />
<input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('hierarchical'); ?>" name="<?php echo $this->get_field_name('hierarchical'); ?>"<?php checked( $hierarchical ); ?> />
<label for="<?php echo $this->get_field_id('hierarchical'); ?>"><?php _e( 'Show hierarchy' ); ?></label></p>
<?php
}
}
function my_categories_init()
{
register_sidebar_widget(__('My Categories Widget'), 'MY_Widget_Categories');
}
add_action("plugins_loaded", "my_categories_init");
?>
You'll need to use register_widget rather than register_sidebar_widget, as that function is for the old style widgets (that didn't extend WP_Widget or were just functions). You should to do this from a function hooked into the widgets_init action. See the Wordpress widgets API documentation for more info: http://codex.wordpress.org/Widgets_API
The following plugin works for me in WP 2.9.
/*
Plugin Name: My Categories Widget
Version: 0.1
*/
class My_Widget_Categories extends WP_Widget {
function My_Widget_Categories() {
$widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "My list or dropdown of categories" ) );
$this->WP_Widget('my_categories', __('My Categories'), $widget_ops);
}
function widget( $args, $instance ) {
extract( $args );
$title = apply_filters('widget_title', empty( $instance['title'] ) ? __( 'Categories' ) : $instance['title']);
$c = $instance['count'] ? '1' : '0';
$h = $instance['hierarchical'] ? '1' : '0';
$d = $instance['dropdown'] ? '1' : '0';
echo $before_widget;
if ( $title )
echo $before_title . $title . $after_title;
$cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h);
if ( $d ) {
$cat_args['show_option_none'] = __('Select Category');
wp_dropdown_categories(apply_filters('widget_categories_dropdown_args', $cat_args));
?>
<script type='text/javascript'>
/* <![CDATA[ */
var dropdown = document.getElementById("cat");
function onCatChange() {
if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
location.href = "<?php echo get_option('home'); ?>/?cat="+dropdown.options[dropdown.selectedIndex].value;
}
}
dropdown.onchange = onCatChange;
/* ]]> */
</script>
<?php
} else {
?>
<ul>
<?php
$cat_args['title_li'] = '';
wp_list_categories(apply_filters('widget_categories_args', $cat_args));
?>
</ul>
<?php
}
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['count'] = $new_instance['count'] ? 1 : 0;
$instance['hierarchical'] = $new_instance['hierarchical'] ? 1 : 0;
$instance['dropdown'] = $new_instance['dropdown'] ? 1 : 0;
return $instance;
}
function form( $instance ) {
//Defaults
$instance = wp_parse_args( (array) $instance, array( 'title' => '') );
$title = esc_attr( $instance['title'] );
$count = isset($instance['count']) ? (bool) $instance['count'] :false;
$hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
$dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
?>
<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><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('dropdown'); ?>" name="<?php echo $this->get_field_name('dropdown'); ?>"<?php checked( $dropdown ); ?> />
<label for="<?php echo $this->get_field_id('dropdown'); ?>"><?php _e( 'Show as dropdown' ); ?></label><br />
<input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>"<?php checked( $count ); ?> />
<label for="<?php echo $this->get_field_id('count'); ?>"><?php _e( 'Show post counts' ); ?></label><br />
<input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('hierarchical'); ?>" name="<?php echo $this->get_field_name('hierarchical'); ?>"<?php checked( $hierarchical ); ?> />
<label for="<?php echo $this->get_field_id('hierarchical'); ?>"><?php _e( 'Show hierarchy' ); ?></label></p>
<?php
}
}
add_action('widgets_init', create_function('', "register_widget('My_Widget_Categories');"));
Categories widget with taxonomy/category select dropdown.
<?php
/**
* Custom Post Type Categories widget class
*
* #since 1.0.0
* #package Custom Post Type Widgets
*/
class Custom_Post_Type_Widgets {
/**
* Sets up a new widget instance
*/
public function __construct() {
add_action( 'widgets_init', array( $this, 'init' ) );
}
/**
* Register widget
*/
public function init() {
if ( ! is_blog_installed() ) {
return;
}
register_widget( 'WP_Custom_Post_Type_Widgets_Categories' );
}
}
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$custom_post_type_widgets = new Custom_Post_Type_Widgets();
/**
* Core class WP_Custom_Post_Type_Widgets_Categories
*
* #since 1.0.0
*/
class WP_Custom_Post_Type_Widgets_Categories extends WP_Widget {
/**
* Sets up a new widget instance.
*
* #since 1.0.0
*
* #access public
*/
public function __construct() {
$widget_ops = array(
'classname' => 'widget_categories',
'description' => __( 'A list or dropdown of categories.', 'custom-post-type-widgets' ),
'customize_selective_refresh' => true,
);
parent::__construct( 'custom-post-type-categories', __( 'Categories (Custom Post Type)', 'custom-post-type-widgets' ), $widget_ops );
}
/**
* Outputs the content for the widget instance.
*
* #since 1.0.0
*
* #access public
*
* #param array $args Display arguments including 'before_title', 'after_title',
* 'before_widget', and 'after_widget'.
* #param array $instance Settings for the current widget instance.
*/
public function widget( $args, $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'Categories', 'custom-post-type-widgets' );
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
$taxonomy = ! empty( $instance['taxonomy'] ) ? $instance['taxonomy'] : 'category';
$c = ! empty( $instance['count'] ) ? (bool) $instance['count'] : false;
$h = ! empty( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
$d = ! empty( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
echo $args['before_widget']; // WPCS: XSS ok.
if ( $title ) {
echo $args['before_title'] . $title . $args['after_title']; // WPCS: XSS ok.
}
$cat_args = array(
'orderby' => 'name',
'taxonomy' => $taxonomy,
'show_count' => $c,
'hierarchical' => $h,
);
if ( $d ) {
$dropdown_id = "{$this->id_base}-dropdown-{$this->number}";
echo '<label class="screen-reader-text" for="' . esc_attr( $dropdown_id ) . '">' . $title . '</label>'; // WPCS: XSS ok.
$cat_args['show_option_none'] = __( 'Select Category', 'custom-post-type-widgets' );
$cat_args['name'] = 'category' === $taxonomy ? 'category_name' : $taxonomy;
$cat_args['id'] = $dropdown_id;
$cat_args['value_field'] = 'slug';
?>
<form action="<?php echo esc_url( home_url() ); ?>" method="get">
<?php
/**
* Filters the arguments for the Categories widget drop-down.
*
* Filter hook: custom_post_type_widgets/categories/widget_categories_dropdown_args
*
* #since 2.8.0
* #since 4.9.0 Added the `$instance` parameter.
*
* #see wp_dropdown_categories()
*
* #param array $cat_args An array of Categories widget drop-down arguments.
* #param array $instance Array of settings for the current widget.
* #param string $this->id Widget id.
* #param string $taxonomy Taxonomy.
*/
wp_dropdown_categories(
apply_filters(
'custom_post_type_widgets/categories/widget_categories_dropdown_args',
$cat_args,
$instance,
$this->id,
$taxonomy
)
);
?>
</form>
<script>
/* <![CDATA[ */
(function() {
var dropdown = document.getElementById( "<?php echo esc_js( $dropdown_id ); ?>" );
function onCatChange() {
if ( dropdown.options[dropdown.selectedIndex].value ) {
return dropdown.form.submit();
}
}
dropdown.onchange = onCatChange;
})();
/* ]]> */
</script>
<?php
}
else {
?>
<ul>
<?php
$cat_args['title_li'] = '';
/**
* Filters the arguments for the Categories widget.
*
* Filter hook: custom_post_type_widgets/categories/widget_categories_args
*
* #see wp_list_categories()
*
* #param array $cat_args An array of Categories widget arguments.
* #param array $instance Array of settings for the current widget.
* #param string $this->id Widget id.
* #param string $taxonomy Taxonomy.
*/
wp_list_categories(
apply_filters(
'custom_post_type_widgets/categories/widget_categories_args',
$cat_args,
$instance,
$this->id,
$taxonomy
)
);
?>
</ul>
<?php
}
echo $args['after_widget']; // WPCS: XSS ok.
}
/**
* Handles updating settings for the current Archives widget instance.
*
* #since 1.0.0
*
* #access public
*
* #param array $new_instance New settings for this instance as input by the user via form() method.
* #param array $old_instance Old settings for this instance.
*
* #return array Updated settings to save.
*/
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = sanitize_text_field( $new_instance['title'] );
$instance['taxonomy'] = stripslashes( $new_instance['taxonomy'] );
$instance['count'] = ! empty( $new_instance['count'] ) ? (bool) $new_instance['count'] : false;
$instance['hierarchical'] = ! empty( $new_instance['hierarchical'] ) ? (bool) $new_instance['hierarchical'] : false;
$instance['dropdown'] = ! empty( $new_instance['dropdown'] ) ? (bool) $new_instance['dropdown'] : false;
return $instance;
}
/**
* Outputs the settings form for the widget.
*
* #since 1.0.0
*
* #access public
*
* #param array $instance Current settings.
*/
public function form( $instance ) {
$title = isset( $instance['title'] ) ? $instance['title'] : '';
$taxonomy = isset( $instance['taxonomy'] ) ? $instance['taxonomy'] : '';
$count = isset( $instance['count'] ) ? (bool) $instance['count'] : false;
$hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
$dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
?>
<p><label for="<?php echo $this->get_field_id( 'title' ); // WPCS: XSS ok. ?>"><?php esc_html_e( 'Title:', 'custom-post-type-widgets' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); // WPCS: XSS ok. ?>" name="<?php echo $this->get_field_name( 'title' ); // WPCS: XSS ok. ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /></p>
<?php
$taxonomies = get_taxonomies( array(), 'objects' );
if ( $taxonomies ) {
printf(
'<p><label for="%1$s">%2$s</label>' .
'<select class="widefat" id="%1$s" name="%3$s">',
$this->get_field_id( 'taxonomy' ),
__( 'Taxonomy:', 'custom-post-type-widgets' ),
$this->get_field_name( 'taxonomy' )
); // WPCS: XSS ok.
foreach ( $taxonomies as $taxobjects => $value ) {
if ( ! $value->hierarchical ) {
continue;
}
if ( 'nav_menu' === $taxobjects || 'link_category' === $taxobjects || 'post_format' === $taxobjects ) {
continue;
}
printf(
'<option value="%s"%s>%s</option>',
esc_attr( $taxobjects ),
selected( $taxobjects, $taxonomy, false ),
esc_html__( $value->label, 'custom-post-type-widgets' ) . ' ' . esc_html( $taxobjects )
);
}
echo '</select></p>';
}
?>
<p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id( 'dropdown' ); // WPCS: XSS ok. ?>" name="<?php echo $this->get_field_name( 'dropdown' ); // WPCS: XSS ok. ?>"<?php checked( $dropdown ); ?> />
<label for="<?php echo $this->get_field_id( 'dropdown' ); // WPCS: XSS ok. ?>"><?php esc_html_e( 'Display as dropdown', 'custom-post-type-widgets' ); ?></label><br />
<input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id( 'count' ); // WPCS: XSS ok. ?>" name="<?php echo $this->get_field_name( 'count' ); // WPCS: XSS ok. ?>"<?php checked( $count ); ?> />
<label for="<?php echo $this->get_field_id( 'count' ); // WPCS: XSS ok. ?>"><?php esc_html_e( 'Show post counts', 'custom-post-type-widgets' ); ?></label><br />
<input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id( 'hierarchical' ); // WPCS: XSS ok. ?>" name="<?php echo $this->get_field_name( 'hierarchical' ); // WPCS: XSS ok. ?>"<?php checked( $hierarchical ); ?> />
<label for="<?php echo $this->get_field_id( 'hierarchical' ); // WPCS: XSS ok. ?>"><?php esc_html_e( 'Show hierarchy', 'custom-post-type-widgets' ); ?></label></p>
<?php
}
}
I think you can use built-in wp function using this.
<?php
$args = array(
'name' => $this->get_field_name('category'),
'show_option_none' => __( 'Select category' ),
'show_count' => 1,
'orderby' => 'name',
'echo' => 0,
'selected' => $category,
'class' => 'widefat'
);
echo wp_dropdown_categories($args);
?>

Categories