Creating a custom categories widget - php

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);
?>

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

WP Widget Categories How to add a description of the number of articles to the widget?

I need to create custom categories widget for WordPress. It should look something like this.
I found in this topic how to create custom categories but I can't understand how to add word - "articles" and remove brackets what we have in standard widget
code of my-category
<?php
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->__construct('my_categories', __('My Categories'), $widget_ops);
}
// FRONTEND
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>
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;
}
/// Saving of settings
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;
}
/// Backend of widget
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
}
}
Is it difficult to implement it in the form of a widget so that later it will be possible to expand the functionality ?
get_terms returns a set of data, so in this data you would also find the total count of each term.
So you could do something like:
$terms = get_terms( [
'taxonomy' => 'post_tag', // or the name of your taxonomy
'hide_empty' => false,
]);
when you would loop the $terms variable you will get an array with the following information:
array(1) {
[0]=>
object(WP_Term) (11) {
["term_id"]=> //int
["name"]=> //string
["slug"]=> //string
["term_group"]=> //int
["term_taxonomy_id"]=> //int
["taxonomy"]=> //string
["description"]=> //string
["parent"]=> //int
["count"]=> // int
["filter"]=> //string
["meta"]=> array(0) { // presumably this would be some returned meta-data?
}
}
}
so in your loop, you could do something like
echo '<ul>';
foreach($terms as $term){
echo "<li>{$term->name} <span class='category-count'>{$term->count}</span></li>"
}
echo '</ul>;
Creating a widget is documented on the WordPress developers page:
https://developer.wordpress.org/themes/functionality/widgets/
But if the document isn't clear, you could have a look at this tutorial on how to create a widget. Doing this will give you the tools to make your own widget:
https://www.hostinger.com/tutorials/how-to-create-custom-widget-in-wordpress

Wordpress shortcode displays widget but not content

I am trying to create a shortcode that will display a current widget and it's contents. It seems to function perfectly fine for wordpress default widgets, however when it comes to my custom widgets it does not work. Any ideas on how to fix it?
Shortcode (I believe the issue stands with $widget_id not working on custom widgets):
function widget_shortcodes($atts) {
global $wp_widget_factory;//Connects to all registered widgets
$parts = shortcode_atts(array( //sets the attributes for the shortcode
'id' => '1', //sets the id field of the shortcode
'type' => 'text' //sets the type field of the shortcode
), $atts );
$widget_id = $atts['id']; //sets the widget id variable to the input id in the shortcode
//this if/elseif statement block checks to see the value of the type field and sets the widget type variable depending on the value
if($atts['type'] == 'calendar'){
$widget_type = 'WP_Widget_Calendar';
} elseif ($atts['type'] == 'posts') {
$widget_type = 'My_Recent_Posts_Widget';
} elseif ($atts['type'] == 'text') {
$widget_type = 'WP_Widget_Text';
} elseif ($atts['type'] == 'form') {
$widget_type = 'quickform_widget';
} elseif ($atts['type'] == 'newsletter') {
$widget_type = 'newsletter_widget';
} elseif ($atts['type'] == 'reviews') {
$widget_type = 'reviews_widget';
}
ob_start(); //initiates the object
if(!empty($widget_type)) {
the_widget($widget_type, $instance, array('widget_id'=> $widget_id)); //gets the widget if the type is correct
$widget_output = ob_get_contents(); //sets the widget output to the object content
} else { //if the type is not supported it displays an error message
echo "<p>Please make sure you have set a valid type in your shortcode.</p>";
echo "<p>Accepted Types: calendar, posts, text, form, newsletter and reviews.<p>";
$widget_output = ob_get_contents(); //sets the widget output to the object content
}
ob_end_clean(); //ends the object
return $widget_output; //returns the widget code
} add_shortcode('widget','widget_shortcodes');
Custom Widget:
<?php // Creating the widget
class newsletter_widget extends WP_Widget {
function __construct() {
parent::__construct(
// Base ID of your widget
'newsletter_widget',
// Widget name will appear in UI
__('Newsletter', 'wpb_widget_domain'),
// Widget description
array( 'description' => __( 'Newsletter widget', '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'] );
$code = apply_filters( 'widget_code', $instance['code'] );
$desc = apply_filters( 'widget_desc', $instance['desc'] );
?>
<aside class="widget widget_newsletter">
<h3><?php echo $title; ?></h3>
<p><?php echo ( $desc ); ?></p>
<?php echo do_shortcode($code);?>
</aside>
<?php }
// Widget Backend
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'Receive our monthly newsletter', 'wpb_widget_domain' );
}
if ( isset( $instance[ 'code' ] ) ) {
$code = $instance[ 'code' ];
}
else {
$code = __( 'Form Code...', 'wpb_widget_domain' );
}
if ( isset( $instance[ 'desc' ] ) ) {
$desc = $instance[ 'desc' ];
}
else {
$desc = __( 'Newsletter description...', '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( 'desc' ); ?>"><?php _e('Newsletter Description:'); ?></label>
<textarea class="widefat" id="<?php echo $this->get_field_id( 'desc' ); ?>" name="<?php echo $this->get_field_name( 'desc' ); ?>" type="text" value="<?php echo esc_attr( $desc ); ?>"><?php echo $desc;?></textarea>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'code' ); ?>"><?php _e( 'Form code:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'code' ); ?>" name="<?php echo $this->get_field_name( 'code' ); ?>" type="text" value="<?php echo esc_attr( $code ); ?>" />
</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['code'] = ( ! empty( $new_instance['code'] ) ) ? strip_tags( $new_instance['code'] ) : '';
$instance['desc'] = ( ! empty( $new_instance['desc'] ) ) ? strip_tags( $new_instance['desc'] ) : '';
return $instance;
}
}
// Register and load the widget
function newsletter_load_widget() {
register_widget( 'newsletter_widget' );
}
add_action( 'widgets_init', 'newsletter_load_widget' );?>

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' );

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

Categories