Some problems in custom widget - php

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();
});
});

Related

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

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

Custom widget Image upload Issue

A day before tomorrow, I developed a custom widget for my Recent WordPress theme. In that widget, have an image upload field with some other fields. I have done everything and the widget is working very well except one problem. When I am dragging the widget in sidebar and giving the information needed in all fields, its showing fine in front-end. But after that when I am trying to change the image from that widget back-end then the save button remain saved. Image doesn’t change.
Codes are below:
class Themeslug_About_Widget extends WP_widget{
public function __construct(){
parent::__construct('author_info', esc_html__( 'About Info Box', 'blogista' ), array(
'description' => esc_html__( 'About Info Box contain brief about Author/ Company.', 'blogista' ),
));
}
public function widget( $args, $instance ){
echo $args['before_widget'];
echo $args['before_title'] . $instance['title'] . $args['after_title'];
?>
<img src="<?php echo $instance['author_box_image']; ?>" alt="<?php echo $instance['title']; ?>" />
<div class="widget-content">
<h3 class="title">
<?php echo $instance['author_name']; ?>
</h3>
</div>
<?php
echo $args['after_widget'];
}
public function form( $instance ){
$title = '';
if( !empty( $instance['title'] ) ) {
$title = $instance['title'];
}
$author_box_image = '';
if( ! empty( $instance['author_box_image'] ) ) {
$author_box_image = $instance['author_box_image'];
}
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e( 'Title:', 'blogista' ); ?></label>
<input type="text" value="<?php echo esc_attr( $title ); ?>" name="<?php echo $this->get_field_name('title'); ?>" id="<?php echo $this->get_field_id('title'); ?>" class="widefat">
</p>
<p>
<button class="button button-primary" id="author_info_image"><?php _e( 'Upload Image', 'blogista' ); ?></button>
<input type="hidden" name="<?php echo $this->get_field_name('author_box_image'); ?>" id="<?php echo $this->get_field_id('author_box_image'); ?>" class="image_link" value="<?php echo esc_url( $author_box_image ); ?>" >
<div class="image_show">
<img src="<?php echo $instance['author_box_image']; ?>" width="200" height="auto" alt="">
</div>
</p>
<?php
}
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? esc_attr( $new_instance['title'] ) : '';
$instance['author_box_image'] = ( ! empty( $new_instance['author_box_image'] ) ) ? esc_url( $new_instance['author_box_image'] ) : '';
return $instance;
}
}
function themeslug_admin_enqueue_scrits(){
wp_enqueue_media();
wp_enqueue_script( 'admin_custom_script', get_theme_file_uri() . '/js/libs/admin_scripts.js', array( 'jquery' ), '1.0', true );
}
add_action( 'admin_enqueue_scripts', 'themeslug_admin_enqueue_scrits' );
Then added the below jQuery code:
(function($){
$(document).ready(function(){
$('button#author_info_image').on("click",function( e ){
e.preventDefault();
var imageUploader = wp.media({
'title' : 'Upload Author Image',
'button' : {
'text' : 'Set The Image'
},
'multiple' : false
});
imageUploader.open();
imageUploader.on("select", function(){
var image = imageUploader.state().get("selection").first().toJSON();
var link = image.url;
$("input.image_link").val( link );
$(".image_show img").attr('src', link);
});
});
});
}(jQuery))
Every thing is working fine first time but when trying to change the image then Widget save button remain saved.
Please Help.
Thanks in Advance.
I will Suggest you to follow my way to create your custom widget using image upload system.
public function widget( $args, $instance ) {
// Our variables from the widget settings
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Default title', 'text_domain' ) : $instance['title'] );
$image = ! empty( $instance['image'] ) ? $instance['image'] : '';
ob_start();
echo $args['before_widget'];
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . $title . $args['after_title'];
}
?>
<?php if($image): ?>
<img src="<?php echo esc_url($image); ?>" alt="">
<?php endif; ?>
<?php
echo $args['after_widget'];
ob_end_flush();
}
And the form function will be:
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'New title', 'text_domain' );
$image = ! empty( $instance['image'] ) ? $instance['image'] : '';
?>
<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( 'image' ); ?>"><?php _e( 'Image:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" type="text" value="<?php echo esc_url( $image ); ?>" />
<button class="upload_image_button button button-primary">Upload Image</button>
</p>
<?php
}
And here is the update function:
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
$instance['image'] = ( ! empty( $new_instance['image'] ) ) ? $new_instance['image'] : '';
return $instance;
}
As you can see, I’ve added a button underneath image input field with class “.upload_image_button”, but it will not work for now and to make it work, need to add our custom admin JavaScript.
First need to create javascript file and put it into your theme, let’s create a file, called our_admin.js in assets/js under your theme folder.
Next you will need to register and enqueue our script to make it load in the admin panel, so lets add few lines to widget class constructor function:
function __construct() {
// Add Widget scripts
add_action('admin_enqueue_scripts', array($this, 'scripts'));
parent::__construct(
'our_widget', // Base ID
__( 'Our Widget Title', 'text_domain' ), // Name
array( 'description' => __( 'Our Widget with media files', 'text_domain' ), ) // Args
);
}
And you will need then “scripts” function in our widget class:
public function scripts()
{
wp_enqueue_script( 'media-upload' );
wp_enqueue_media();
wp_enqueue_script('our_admin', get_template_directory_uri() . '/assets/js/our_admin.js', array('jquery'));
}
As you can notice, I added wp_enqueue_script( ‘media-upload’ ); and wp_enqueue_media(); to enqueue media library popup scripts.
And finally, here is js script, that will call WordPress media library popup and put selected image into the input field:
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();
});
});
Now compare your code and you will see the error.
I will suggest to use Plugin to show author information to save your time.

When uploading an image, the image doesn't change but the image URL is correct

I'm trying out wordpress widgets, and I took this code from https://vedmant.com/using-wordpress-media-library-in-widgets-options/. The widget is supposed to let you upload your own images via the wordpress media library. The code works to open up the media library, upload an image and choose it, but the image won't change to show the new image.
Here's the code (also on the site):
I read some other treads on similar things, and tried to look up refreshing widgets, but I can't seem to find the answer I'm looking for. I think the problem is that the textbox will fill with the image URL but it won't refresh because Wordpress thinks nothing changed. Any ideas on what I can do?
<?php
add_action( 'widgets_init', 'myw_init' );
function myw_init() {
register_widget( 'my_widget' );
}
class my_widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
function __construct() {
// Add Widget scripts
add_action('admin_enqueue_scripts', array($this, 'scripts'));
parent::__construct(
'my_widget', // Base ID
__( 'Our Widget Title', 'text_domain' ), // Name
array( 'description' => __( 'Our Widget with media files', 'text_domain' ), ) // Args
);
}
/**
* Enqueue scripts
*/
public function scripts()
{
wp_enqueue_script( 'media-upload' );
wp_enqueue_media();
wp_enqueue_script('mfc-media-upload', get_template_directory_uri() . '/../../plugins/my-featured-content/mfc-media-upload.js', array('jquery'));
}
/**
* Outputs the content of the widget
*
* #param array $args
* #param array $instance
*/
public function widget( $args, $instance ) {
// Our variables from the widget settings
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Default title', 'text_domain' ) : $instance['title'] );
$image = ! empty( $instance['image'] ) ? $instance['image'] : '';
ob_start();
echo $args['before_widget'];
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . $title . $args['after_title'];
}
?>
<?php if($image): ?>
<img src="<?php echo esc_url($image); ?>" alt="">
<?php endif; ?>
<?php
echo $args['after_widget'];
ob_end_flush();
}
/**
* Outputs the options form on admin
*
* #param array $instance The widget options
*/
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'New title', 'text_domain' );
$image = ! empty( $instance['image'] ) ? $instance['image'] : '';
?>
<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( 'image' ); ?>"><?php _e( 'Image:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" type="text" value="<?php echo esc_url( $image ); ?>" />
<button class="upload_image_button button button-primary">Upload Image</button>
</p>
<?php
}
/**
* Processing widget options on save
*
* #param array $new_instance The new options
* #param array $old_instance The previous options
*
* #return array
*/
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
$instance['image'] = ( ! empty( $new_instance['image'] ) ) ? $new_instance['image'] : '';
return $instance;
}
}
And for the jQuery:
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();
});
});
You can add a query parameter to the image URL to force it to be unique, e.g.:
<img src="<?php echo esc_url($image); ?>?<?php echo time() ?>" alt="">

Notice: undefined index in wordpress widget

I have done this widget. In the admin area, when I change the value of the variables number, small and large are not saved. And in the frontend i have this notice:
Notice: Undefined index: number in /home/masqueci/public_html/wp-content/themes/Flatnews/includes/theme-widgets.php on line 272
The same for all variables except the title variable.
This is the widget code:
/* CUSTOM TAG CLOUD */
class Tag_cloud extends WP_Widget {
function Tag_cloud() {
/* Widget settings. */
$widget_ops = array( 'classname' => 'Tag_cloud', 'description' => __('Display tag cloud.', 'fabulous') );
/* Widget control settings. */
$control_ops = array( 'width' => 200, 'height' => 350, 'id_base' => 'tag_cloud' );
/* Create the widget. */
$this->WP_Widget( 'tag_cloud', __('Fabulous tag cloud', 'fabulous'), $widget_ops, $control_ops );
}
function widget( $args, $instance ) {
extract( $args );
/* User-selected settings. */
$title = apply_filters('widget_title', $instance['title'] );
$number = $instance['number'];
$small = $instance['small'];
$large = $instance['large'];
/* Before widget (defined by themes). */
echo $before_widget;
/* Title of widget (before and after defined by themes). */
if ( $title )
echo $before_title . '<i class="fa fa-tags"></i>' . $title . $after_title;
echo fab_show_tags ($small, $large, $number);
/* After widget (defined by themes). */
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
/* Strip tags (if needed) and update the widget settings. */
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['number'] = strip_tags( $new_instance['number'] );
$instance['small'] = strip_tags( $new_instance['small'] );
$instance['large'] = strip_tags( $new_instance['large'] );
return $instance;
}
function form( $instance ) {
/* Set up some default widget settings. */
$defaults = array( 'title' => 'TAG CLOUD', 'number' => '10', 'small' => '8', 'large' => '12');
$instance = wp_parse_args( (array) $instance, $defaults );
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">
<?php _e('Title:', 'fabulous') ?>
</label>
<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'number' ); ?>">
<?php _e('Number:', 'fabulous') ?>
</label>
<input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" value="<?php echo $instance['number']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'small' ); ?>">
<?php _e('Smallest:', 'fabulous') ?>
</label>
<input id="<?php echo $this->get_field_id( 'small' ); ?>" name="<?php echo $this->get_field_name( 'small' ); ?>" value="<?php echo $instance['small']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'large' ); ?>">
<?php _e('Largest:', 'fabulous') ?>
</label>
<input id="<?php echo $this->get_field_id( 'large' ); ?>" name="<?php echo $this->get_field_name( 'large' ); ?>" value="<?php echo $instance['large']; ?>" style="width:100%;" />
</p>
<?php
}
}
I dont know what is bad, i have done other widgets and i haven´t had this problem i think i have write the same code. Any help this?
You need to assign a value to variables before calling them. Do not always assume a user will give you all data required.
function widget( $args, $instance ) {
extract( $args );
/* User-selected settings. */
$title = null; $number = null; $small = null; $large = null;
if (! empty( $instance['title'] ) ) { $title = apply_filters('widget_title', $instance['title'] ) }
if (! empty( $instance['number'] ) ) { $number = $instance['number']; }
if (! empty( $instance['small'] ) ) { $small = $instance['small']; }
if (! empty( $instance['large'] ) ) { $large = $instance['large']; }
/* Before widget (defined by themes). */
echo $before_widget;
/* Title of widget (before and after defined by themes). */
if ( $title )
echo $before_title . '<i class="fa fa-tags"></i>' . $title . $after_title;
echo fab_show_tags ($small, $large, $number);
/* After widget (defined by themes). */
echo $after_widget;
}
Place this at the top of your function like so:
class My_Widget extends WP_Widget {
protected $defaults;
function _construct(){
$this->defaults = array(
'title' => '',
'number' => 5,
'small' => 1,
'large' => 10,
);
}
// etc etc rest of class functions ...
}
Then include this extra line at the top of your form function kind of like so:
function form($instance) {
$instance = wp_parse_args( (array) $instance, $this->defaults );
// etc etc, rest of form ...
}
Obviously it may make sense for you to setup real defaults, but empty ones may at least remove the warnings and notices you receive.
I just updated my widget plugin. It had the same issue as yours. Here is the example to use that goes with my answer:
http://plugins.svn.wordpress.org/sm-sticky-featured-widget/tags/1.2.5/sticky-featured-widget.php

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