Custom WP_Widget not appearing in admin panel - php

In order to apply some changes to the default Recent Posts Widget I have copied and modified it to my needs. It is included and registered in my template's functions.php and when loading the widget-section in the admin panel its constructor is run.
The problem is that it does not appear in the list of available widgets and thus can not be used. The problem also occurs when I try the minimal example from http://www.darrenhoyt.com/2009/12/22/creating-custom-wordpress-widgets/, so I think I missed something important, but don't know what.
Until now my theme is a modified clone of https://wordpress.org/extend/themes/toolbox.
This explains the many occurrences of toolbox_ in the code.
Following are code excerpts from functions.php and
inc/widgets.php. I can provide more code if needed. Please let me
know in the comments.
Code:
<?php
// BEGIN functions.php
if ( ! function_exists( 'toolbox_setup' ) ):
/**
* Sets up theme defaults and registers support for various WordPress features.
*
* Note that this function is hooked into the after_setup_theme hook, which runs
* before the init hook. The init hook is too late for some features, such as indicating
* support post thumbnails.
*
* To override toolbox_setup() in a child theme, add your own toolbox_setup to your child theme's
* functions.php file.
*/
function toolbox_setup() {
// [...]
require( get_template_directory() . '/inc/widgets.php' );
// [...]
}
endif; // toolbox_setup
/**
* Tell WordPress to run toolbox_setup() when the 'after_setup_theme' hook is run.
*/
add_action( 'after_setup_theme', 'toolbox_setup' );
/**
* Register widgetized area and update sidebar with default widgets
*/
function toolbox_widgets_init() {
register_widget("My_Widget_Recent_Posts");
register_sidebar( array(
'name' => __( 'Sidebar 1', 'toolbox' ),
'id' => 'sidebar-1',
'before_widget' => '<aside id="%1$s" class="widget %2$s">',
'after_widget' => "</aside>",
'before_title' => '<h1 class="widget-title small">',
'after_title' => '</h1>',
) );
}
add_action( 'init', 'toolbox_widgets_init' );
// END functions.php
?>
<?php
// BEGIN inc/widgets.php
/**
* Recent_Posts widget class
*
* #since 2.8.0
*/
class My_Widget_Recent_Posts extends WP_Widget {
function __construct() {
$widget_ops = array('classname' => 'my_widget_recent_entries', 'description' => __( "The most recent posts on your site (modified)") );
parent::__construct('my-recent-posts', __('Recent Posts (modified)'), $widget_ops);
$this->alt_option_name = 'my_widget_recent_entries';
add_action( 'save_post', array(&$this, 'flush_widget_cache') );
add_action( 'deleted_post', array(&$this, 'flush_widget_cache') );
add_action( 'switch_theme', array(&$this, 'flush_widget_cache') );
}
function widget($args, $instance) {
$cache = wp_cache_get('my_widget_recent_posts', 'widget');
if ( !is_array($cache) )
$cache = array();
if ( ! isset( $args['widget_id'] ) )
$args['widget_id'] = $this->id;
if ( isset( $cache[ $args['widget_id'] ] ) ) {
echo $cache[ $args['widget_id'] ];
return;
}
ob_start();
extract($args);
$title = apply_filters('widget_title', empty($instance['title']) ? __('Recent Posts') : $instance['title'], $instance, $this->id_base);
if ( empty( $instance['number'] ) || ! $number = absint( $instance['number'] ) )
$number = 10;
$r = new WP_Query( apply_filters( 'widget_posts_args', array( 'posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true ) ) );
if ($r->have_posts()) :
?>
<?php echo $before_widget; ?>
<?php if ( $title ) echo $before_title . $title . $after_title; ?>
<ul>
<?php while ($r->have_posts()) : $r->the_post(); ?>
<li><?php if ( get_the_title() ) the_title(); else the_ID(); ?>
<?php the_content(); ?></li>
<?php endwhile; ?>
</ul>
<?php echo $after_widget; ?>
<?php
// Reset the global $the_post as this query will have stomped on it
wp_reset_postdata();
endif;
$cache[$args['widget_id']] = ob_get_flush();
wp_cache_set('my_widget_recent_posts', $cache, 'widget');
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['number'] = (int) $new_instance['number'];
$this->flush_widget_cache();
$alloptions = wp_cache_get( 'alloptions', 'options' );
if ( isset($alloptions['my_widget_recent_entries']) )
delete_option('my_widget_recent_entries');
return $instance;
}
function flush_widget_cache() {
wp_cache_delete('my_widget_recent_posts', 'widget');
}
function form( $instance ) {
$title = isset($instance['title']) ? esc_attr($instance['title']) : '';
$number = isset($instance['number']) ? absint($instance['number']) : 5;
?>
<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><label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of posts to show:'); ?></label>
<input id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>
<?php
}
}
// END inc/widgets.php
?>

You have to hook register_widget to the widgets_init action, NOT to the init action. In your case it is something like this:
<?php
add_action( 'widgets_init', 'toolbox_widgets_init' );
function toolbox_widgets_init() {
register_widget("My_Widget_Recent_Posts");
}
?>

Ok lets do some debugging test:
echo "include widget file";
require( get_template_directory() . '/inc/widgets.php' );
Also:
echo "register widget";
register_widget("My_Widget_Recent_Posts");
Then:
function __construct() {
echo "widget class";
Check your HTML to see what parts echoed and what parts didn't you may get Headers already sent error, which you can ignore. Hopefully we can see which part is not being triggered to narrow down where the problem is.

Registering the widget as follows solved the problem for me, but is not very elegant in my opinion. Right behind the class definition I inserted the line
<?php
add_action( 'widgets_init', create_function('',
'return register_widget("My_Widget_Recent_Posts");') );
?>
And removed the registration from toolbox_widgets_init() where I think it belongs.
In case somebody can explain why it has to be this way round or what I could change so that it would work like I intended to do it before I would highly appreciate comments. But for now the actual problem is solved.

Related

Creating a widget to open mini-cart

I have a plugin which adds a mini cart to my website so when I add a product to the basket the mini cart pops out from the page.
The whole plugin works great. The only thing I want to do is create a widget to put in the header area of the website to open the mini cart, just like the hovering basket does in the bottom right hand corner of the page.
The code that it says to use is:
public_woo_amc_show()
The problem is, that I'm totally unsure, how to add a custom widget. I've googled and managed to code this code:
// Register and load the widget
function wpb_load_widget() {
register_widget( 'wpb_widget' );
}
add_action( 'widgets_init', 'wpb_load_widget' );
// Creating the widget
class wpb_widget extends WP_Widget {
function __construct() {
parent::__construct(
// Base ID of your widget
'wpb_widget',
// Widget name will appear in UI
__( 'WPBeginner Widget', 'wpb_widget_domain' ),
// Widget description
array( 'description' => __( 'Sample widget based on WPBeginner Tutorial', 'wpb_widget_domain' ), )
);
}
// Creating widget front-end
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
All I want is an icon that I can click and it pops the mini-cart out exactly how it does on the website above already.
I've tried adding this code where I thought it would go within this widget but I'm no expert and am definitely limited with JavaScript.

Wordpress: Add html code to widget area without using a text widget

Normally, you can create a text widget if you want to add html code to the sidebar area of Wordpress. But this won't work in my case, let me explain it to you:
I want to place an image (with an link) to the sidebar, which doesn't end up in a widget box with white background. Instead the image should be placed directly in the widget area.
Currently, my wordpress theme applies a white background to all widgets with the css class .widget by default. As far as I know, every widget is assigned with this class.
Is there a way to inject the html code using a hook in the functions.php of my theme folder? Or maybe using the sidebar.php file?
You can use Widgets API
if ( !class_exists( 'MyCustomWidgetClass' ) ) {
// Create Custom Draggable Widget
class MyCustomWidgetClass extends WP_Widget {
// Register widget with WordPress.
public function __construct() {
parent::__construct(
'my_custom_widget',
'My Custom Widget Title',
array( 'description' => __( 'Custom Widget Decription', 'cmk' ), )
);
}
//Front-end display of widget.
public function widget( $args, $instance ) {
$content = 'Bla Bla'; // Add HTML code, or call the function that contains your HTML code
extract( $args );
$title = apply_filters( 'widget_title', $instance['title'] );
echo $before_widget;
if ( ! empty( $title ) )
echo $before_title . $title . $after_title;
echo $content;
echo $after_widget;
}
//Sanitize widget form values as they are saved.
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = strip_tags( $new_instance['title'] );
return $instance;
}
// Back-end widget form.
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
} else {
$title = __( 'My Custom Widget Title', 'cmk' );
} ?>
<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
}
}
add_action( 'widgets_init', create_function('', 'return register_widget("MyCustomWidgetClass");') );
}
You can use the inline css to change the background color of your image if you want to add image using text widget.
<a href="http://www.w3schools.com/">
<img src="Your Image Path" style="background-color: beige;">
</a>

Creating a wishlist widget

I am building quite a large website using WooCommerce and their wishlists addon. What I'd like to do is add a widget to the sidebar that shows the customers wishlists when they are logged in. There doesn't seem to be anything available at the moment so I thought I'd build it myself....
In the actual wishlists plugin files I found shortcodes-init.php which I thought would be good as a starting point to create the widget, as it should check if the person is logged in and if so, display their wishlists. All I then had to do was create the actual widget.
I created a new file that I added to the wishlists plugin folder (because I know my custom file won't get overwritten), set up the widget and added the code found in the shortcodes to display wishlists.
This is what I have:
// Creating the widget
class wl_widget extends WP_Widget {
function __construct() {
parent::__construct(
// Base ID of your widget
'wl_widget',
// Widget name will appear in UI
__('Boards Widget', 'wl_widget_domain'),
// Widget description
array( 'description' => __( 'Widget to add show customers boards', 'wl_widget_domain' ), ) );
}
// Creating widget front-end
// This is where the action happens
public function widget( $args, $instance ) {
extract( $args );
$title = apply_filters( 'widget_title', $instance['title'] );
// before and after widget arguments are defined by themes
echo $args['before_widget'];
if ( $title )
echo $before_title . $title . $after_title;
//We need to force WooCommerce to set the session cookie
if ( !is_admin() && !WC_Wishlist_Compatibility::WC()->session->has_session() ) {
WC_Wishlist_Compatibility::WC()->session->set_customer_session_cookie( true );
}
ob_start();
if (is_user_logged_in() || (WC_Wishlists_Settings::get_setting('wc_wishlist_guest_enabled', 'enabled') == 'enabled')) {
//woocommerce_wishlists_get_template('my-lists.php');
echo "loggedin";
} else {
//woocommerce_wishlists_get_template('guest-disabled.php');
echo "loggedout";
}
return ob_get_clean();
echo $args['after_widget'];
}
// Widget Backend
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'New title', 'wl_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>
This widget automatically displays boards when the person is logged in so there is no further settings needed.
</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 btn_widget ends here
// Register and load the widget
function wl_load_widget() {
register_widget( 'wl_widget' );
}
add_action( 'widgets_init', 'wl_load_widget' );
The problem I have is that this does not see if the customer is logged in or not and actually breaks the page. This is the code that seems to be the problem.
//We need to force WooCommerce to set the session cookie
if ( !is_admin() && !WC_Wishlist_Compatibility::WC()->session->has_session() ) {
WC_Wishlist_Compatibility::WC()->session->set_customer_session_cookie( true );
}
Does anyone know how to fix this or another way to get the customers wishlists?
Thanks :)

Custom WordPress widget is wrapping all other widgets below it

I am trying to write a custom widget to display our teamspeak server info. This is what I have so far:
<?php
/*
Plugin Name: Site Plugin for RealmReborn.co
Description: Site specific code changes for RealmReborn.co
*/
/* Start Adding Functions Below this Line */
// 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
?>
<iframe src="http://cache.www.gametracker.com/components/html0/?host=tsserver.co:9987&bgColor=333333&fontColor=CCCCCC&titleBgColor=222222&titleColor=FF9900&borderColor=555555&linkColor=FFCC00&borderLinkColor=222222&showMap=0&currentPlayersHeight=220&showCurrPlayers=1&showTopPlayers=0&showBlogs=0&width=265"
frameborder="0" scrolling="no" width="265" height="408"></iframe>
<?php
}
// 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' );
/* Stop Adding Functions Below this Line */
// Creating the widget
?>
I got this code from a wordpress help site and tried to follow the instructions but I'm doing something wrong.
My site is realmreborn.co and I am trying to display the widget on the right side.
You will notice that the Teamspeak widget is wrapping all of the widgets below it on the right side:
I do not know what I did wrong, I've tried to make adjustments to the code but nothing I seem to do seems to fix it. Did I miss a bracket or not implement something correctly?
Any help would be greatly appreciated!
This is a total guess but maybe you need to do a echo $args['after_widget']; just before the closing brace after the iframe.
I think something wrong with html, check all tags are closed, check for echo $args['after_widget']; - I don't see it in code. It's all markup, some fixed and it would be all right)

Widget in wordpress i want the content to update on selected dropdown

I cannot figure out how to change the content om my custom widget.
I am creating a dropdown in the Form function that dropdown items is generated from a table. And when i pick one of the dropdown items and hit the save button i want to load a content from my DB and set the widgets content.
if i pick Item 1 in the dropdown i want to query my db with item 1 and update the content of the widgets content.
How do i do this ? i am aware of a ajax call to get the data from the DB but how do i set the data to the widgets content ?
function form($instance){
$select = esc_attr($instance['select']);
?>
<select>
<?php
require_once('../wp-load.php');
global $wpdb;
$query = $wpdb->get_results("SELECT titel FROM wp_layout");
foreach($query as $result){
echo '<option value="' .$result->titel. '">' .$result->titel. '</option>';
}
?>
</select>
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['select'] = strip_tags($new_instance['select']);
return $instance;
}
And i need the
function widget()
To make a custom wordpress widget, then first you have to make your custom widget class that will extend the WP_Widget class of wordpress core.
// Creating the widget
class My_Custom_Widget extends WP_Widget {
function __construct() {
parent::__construct(
// Base ID of your widget
'my_custom_widget',
// Widget name will appear in UI
__('My Custom Widget', 'my_custom_widget_domain'),
// Widget description
array( 'description' => __( 'Sample widget', 'my_custom_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!', 'my_custom_widget_domain' );
echo $args['after_widget'];
}
// Widget Backend
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'New title', 'my_custom_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 ends here
And Register your widget:
// Register and load the widget
function custom_load_widget() {
register_widget( 'my_custom_widget' );
}
add_action( 'widgets_init', 'custom_load_widget' );
And now if you want to make ajax calls then just regitsre your ajax calls via hooks explained Wordpress AJAX

Categories