WordPress Custom Menu Widget ==> change to 2-column - php

I am trying to create a Custom Menu Widget that has two columns (i.e., wherein I can select two different menus and have them display side-by-side within a single sidebar widget).
I found a tutorial on how to create a two column text widget, however I cannot figure out how to edit the Custom Menu widget functions to add and implement an additional menu -- my attempts to create an additional menu variable (i.e., "$menus1" and "$menus2" below) break WordPress ("unexpected T string" error).
Does the "$instance" array have a pre-defined key called 'nav_menu' or are this key and its value created by the "form" function? If the latter, can I define 'nav_menu1' and 'nav_menu2' keys (I tried this before but also got the "unexpected T string" error)?
<?php
/**
* Custom Menu widget copied from default WP Widget Class and adjusted for 2-columns
*/
class SO_ABC_Tag_List_Widget_2col extends WP_Widget {
function __construct() {
$widget_ops = array( 'description' => __('By adding this widget you can select your alphabetical tags menu to display on your website.') );
parent::__construct( 'so_abc_tags_2col', __('SO ABC Tag List 2 col'), $widget_ops );
}
function widget($args, $instance) {
// Get menu
$nav_menu1 = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;
$nav_menu2 = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;
if ( !$nav_menu )
return;
$instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
echo $args['before_widget'];
if ( !empty($instance['title']) )
echo $args['before_title'] . '<i class="icon-tags"></i> ' . $instance['title'] . $args['after_title'];
<div style="float: left; width: 45%">
wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu1 ) );
</div>
<div style="float: left; width: 45%"></div>
wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu2 ) );
</div>
echo $args['after_widget'];
}
function update( $new_instance, $old_instance ) {
$instance['title'] = strip_tags( stripslashes($new_instance['title']) );
$instance['nav_menu'] = (int) $new_instance['nav_menu'];
$instance['nav_menu'] = (int) $new_instance['nav_menu'];
return $instance;
}
function form( $instance ) {
$title = isset( $instance['title'] ) ? $instance['title'] : '';
$nav_menu1 = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';
$nav_menu2 = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';
// Get menus
$menus1 = get_terms( 'nav_menu', array( 'hide_empty' => false ) );
$menus1 = get_terms( 'nav_menu', array( 'hide_empty' => false ) );
// If no menus exists, direct the user to go and create some.
if (( !$menus1 ) AND ( !menus2 )) {
echo '<p>'. sprintf( __('No menus have been created yet. Create some.'), admin_url('nav-menus.php') ) .'</p>';
return;
}
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo $title; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('nav_menu'); ?>"><?php _e('Select Menu:'); ?></label>
<select id="<?php echo $this->get_field_id('nav_menu'); ?>" name="<?php echo $this->get_field_name('nav_menu'); ?>">
<?php
foreach ( $menus1 as $menu1 ) {
echo '<option value="' . $menu1->term_id . '"'
. selected( $nav_menu, $menu1->term_id, false )
. '>'. $menu1->name . '</option>';
}
?>
</select>
</p>
<p>
<label for="<?php echo $this->get_field_id('nav_menu'); ?>"><?php _e('Select Menu:'); ?></label>
<select id="<?php echo $this->get_field_id('nav_menu'); ?>" name="<?php echo $this->get_field_name('nav_menu'); ?>">
<?php
foreach ( $menus2 as $menu2 ) {
echo '<option value="' . $menu2->term_id . '"'
. selected( $nav_menu, $menu2->term_id, false )
. '>'. $menu2->name . '</option>';
}
?>
</select>
</p>
<?php
}
}

You have html and php code mixed together which certainly would cause an error
if ( !empty($instance['title']) )
echo $args['before_title'] . '<i class="icon-tags"></i> ' . $instance['title'] . $args['after_title'];
wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu1 ) );
wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu2 ) );
echo $args['after_widget'];
}
Fix that first then see if it still doesnt work.
You also haven't finished changing all the references from menu1 to menu2. And yes you will need to change the the key for $instance and probably get_terms - plus theres some field id stuff in the form function thats duplicated.
But I'm not sure what you want to achieve.
What you're trying to do will output 2 different menus in a single widget.
My suggestion would be to put two menu widgets in the same area and then use css to make them go side by side.

Related

ACF Custom Widget on Woocommerce Shop Page (Repeater)

I have a big issue with an ACF custom widget, I would like to setup a Repeater style using ACF Pro displayed in the Sidebar on the Shop page of WooCommerce platform. The problem is - it doesn't work. It doesn't display the image sub_field called "photoTest" in the page_sliders.
I downloaded the widget and tried to figure out this but I have no idea where is the problem.. ACF rule is linked with the widget, in the functions there is an absolute path to the custom widget but I think the problem might be with the custom widget itself so here is the code.
<?php
class ACF_Custom_Widget extends WP_Widget {
function __construct() {
parent::__construct(
'acf_custom_widget',
__('ACF Custom Widget', 'text_domain'),
array( 'description' => __( 'A custom ACF widget', 'text_domain' ), 'classname' => 'acf-custom-widget' ) // Args
);
}
public function widget( $args, $instance ) {
echo $args['before_widget'];
if ( !empty($instance['title']) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ). $args['after_title'];
}
echo get_field('title', 'widget_' . $args['widget_id']);?>
<?php
if ( is_shop() ){
$page_id = get_option( 'woocommerce_shop_page_id' );
}
else {
$page_id = get_the_ID();
}
if( have_rows('page_sliders', $page_id) ): ?>
<div id="carouselControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<?php while( have_rows('page_sliders', $page_id) ): the_row();
// vars
$image = get_sub_field('photoTest', $page_id);
?>
<div class="photo-wrap">
<img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>" />
</div>
<?php endwhile; ?>
</div>
</div>
<?php endif; ?>
<?php
echo $args['after_widget'];
}
public function form( $instance ) {
if ( isset($instance['title']) ) {
$title = $instance['title'];
}
?>
<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
}
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
return $instance;
}
}
add_action( 'widgets_init', function(){
register_widget( 'ACF_Custom_Widget' );
});
Please help..thank you.

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

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

Is get_field_id() Necessary for Form Filed in WordPress Widget API?

I'm trying to create a custom widget for my plugin and following the codex.
This is what I have so far. It's working and saves and displays the saved option value.
<?php
/**
* Plugin Name: Sample Widget
*/
$colors = array('red', 'blue', 'yellow');
update_option('sample_widget', $colors);
add_action( 'widgets_init', create_function( '', 'register_widget( "Sample_Widget" );' ) );
class Sample_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'foo_widget',
'Sample Widget',
array( 'description' => __( 'This is a description of the sample widget', 'text_domain' ), ) // Args
);
}
public function widget( $args, $instance ) {
extract( $args );
$title = apply_filters( 'widget_title', $instance['title'] );
$color = apply_filters( 'widget_title', $instance['color'] );
echo $before_widget;
if ( ! empty( $title ) )
echo $before_title . $title . $after_title;
echo 'the selected color is ' . $color . '<br />';
echo $after_widget;
}
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['color'] = $new_instance['color'];
return $instance;
}
public function form( $instance ) {
if ( isset( $instance[ 'title' ] ) ) {
$title = $instance[ 'title' ];
}
else {
$title = __( 'New title', 'text_domain' );
}
if ( isset( $instance[ 'color' ] ) ) {
$selected_color = $instance[ 'color' ];
}
$colors = get_option('sample_widget');
?>
<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>
<select name="<?php echo $this->get_field_name( 'color' ); ?>" id="<?php echo $this->get_field_id( 'color' ); ?>">
<option value="">Select...</option>
<?php foreach($colors as $color) echo '<option value="' . esc_attr( $color ) . '" ' . ($color == $selected_color ? 'selected="Selected"' : '') . '>'. $color .'</option>'; ?>
</select>
</p>
<?php
}
}
I have two questions:
What is id="<?php echo $this->get_field_id( 'color' ); ?>" for? I removed this part of the line and it seems to work fine. I placed it to just copy the codex working code.
In the constructor, the first parameter in parent::__construct() is a base ID. Could this be any string value? I changed it to something else from foo_widget and it seems to work.
Thanks for your info.
The id="<?php echo $this->get_field_id( 'color' ); ?>" is to generate a unique 'id' value for this option. Typically this is so the object can be manipulated via JS.
The id_base of foo_widget is a Root id for all widgets of this type. It is an Optional Base ID for the widget, in lower case, and if left empty a portion of the widget's class name will be used. It has to be unique. This will be appended to with the individual widget's ID number i.e.foo_widget-001
Hope this helps you!

How to add another text box to WP_Widget_Text

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

Categories