How to create dynamic field names in a wordpress widget - wordpress

I'm writing a WordPress widget plugin with a settings form of HTML checkboxes. Each checkbox corresponds to a different post_type. This is my code:
function form($instance) {
$defaults = array( 'num_posts' => 5 );
$instance = wp_parse_args( (array) $instance, $defaults );
$num_posts = $instance['num_posts'];
$post_types = get_post_types();
$instance['post_types'] = $post_types;
?>
<p>Number of posts to show: <input class="widefat" name="<?php echo $this->get_field_name( 'num_posts' ); ?>" type="number" value="<?php echo esc_attr( $num_posts ); ?>" /></p>
<p>Filter by Post Type: <ul>
<?php foreach ($post_types as $post_type) { ?>
<li><input name="<?php echo $post_type; ?>" type="checkbox" <?php checked( $post_types, 'on' ); ?> /><label for="<?php echo $post_type; ?>" /><?php echo $post_type; ?></label></li>
<?php
} ?>
</ul></p>
My question is, how do I generate dynamic $instance names for the checkboxes in the loop? I realize I should be able to do something like $this->get_field_name( 'myname' );, but how to make that dynamic?
NOTE: The above code sample simply outputs the post_type for the name property instead of using get_field_name; this is not a solution, just a wall I hit.
Thanks!
EDIT:
I narrowed the issue to the widget update function, which doesn't seem to work when using a foreach loop. Another unanswered issue on stackoverflow describes something similar. PHP - Wordpress - Plugin Widget Update Function - Update array values [Foreach Loop not Working]
Here's my code (slightly revised) including the update function.
// build the widget settings form
function form( $instance ) {
$defaults = array( 'num_posts' => 5 );
$instance = wp_parse_args( (array) $instance, $defaults );
$num_posts = $instance['num_posts'];
foreach ( get_post_types() as $post_type ) {
$post_types_array[$post_type] = $post_type;
}
$instance['post_types'] = $post_types_array;
$post_types = $instance['post_types'];
echo '<pre>';
print_r($instance);
echo '</pre>';
?>
<p>Number of posts to show: <input class="widefat" name="<?php echo $this->get_field_name( 'num_posts' ); ?>" type="number" value="<?php echo esc_attr( $num_posts ); ?>" /></p>
<p>Filter by Post Type: <ul>
<?php foreach ( $post_types as $post_type ) { ?>
<li><input name="<?php echo $this->get_field_name( $post_type ); ?>" type="checkbox" <?php checked( $this->get_field_name( $post_type ) ); ?> /><label for="<?php echo $this->get_field_name( $post_type ); ?>" /><?php echo $post_type; ?></label></li>
<?php
} ?>
</ul></p>
<?php
}
// save the widget settings
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['num_posts'] = strip_tags( $new_instance['num_posts'] );
foreach ( $instance['post_types'] as $post_type ) {
$instance['post_types'][$post_type] = strip_tags( $new_instance['post_types'][$post_type] );
}
return $instance;
}

Related

How to create WordPress widget using custom menu select

I'm creating a custom widget for WordPress but am wanting to use the same select menu as the default Custom Menu widget does. So far what I have works except the selected menu isn't being saved or displayed on the frontend. Any help or direction with this is appreciated. Thanks.
For brevity, I've removed extra widget options, so this is basically going to look very close to the Custom Menu widget:
class kedc_mini_sitemap extends WP_Widget {
/*constructor*/
function kedc_mini_sitemap() {
parent::WP_Widget(false, $name = 'Mini Sitemap');
}
/**/
function widget($args, $instance) {
extract( $args );
// widget options
$title = apply_filters('widget_title', $instance['title']);
$nav_menu1 = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;
$checkbox = $instance['checkbox'];
echo $before_widget;
if ($title) {
echo $before_title . $title . $after_title;
}
if ($nav_menu1) {
echo wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu1 ) );
}
if ($checkbox == true) {
echo 'This message is displayed if our checkbox is checked.';
}
echo $after_widget;
}
/* saves options chosen from the widgets panel */
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['nav_menu'] = (int) $new_instance['nav_menu'];
$instance['checkbox'] = strip_tags($new_instance['checkbox']);
return $instance;
}
/* display widget in widgets panel */
function form($instance) {
$title = esc_attr($instance['title']);
$nav_menu1 = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';
$checkbox = esc_attr($instance['checkbox']);
$menus1 = get_terms( 'nav_menu', array( 'hide_empty' => false ) );
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Widget 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('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>
<input id="<?php echo $this->get_field_id('checkbox'); ?>" name="<?php echo $this->get_field_name('checkbox'); ?>" type="checkbox" value="1" <?php checked( '1', $checkbox ); ?>/>
<label for="<?php echo $this->get_field_id('checkbox'); ?>"><?php _e('Do you want this to display as 2 columns?'); ?></label>
</p>
<?php
}
}
// register widget
add_action('widgets_init', create_function('', 'return register_widget("kedc_mini_sitemap");'));
You have a typo in the form() function: $nav_menu1 and $nav_menu.
Use more meaningful, strict and descriptive names for your variables. For example, $menus1 could be called $get_nav_menus.
Use a good IDE, like NetBeans or similar, and check the WordPress Coding Standards Handbook.
Oh, yes, your code is dumping PHP Notices, always develop with WP_DEBUG enabled.

Wordpress Custom Widget Select Options Not Saving

I'm very new to coding Wordpress plugins/widgets (this is my first time!). I've built a very basic Wordpress plugin which consists of 2 text inputs and a select field. The text inputs work fine however the select box doesn't appear to be saving when I hit the "Save" button.
Here is my plugin code:
<?php
/* Plugin Name: Sidebar Box
Plugin URI: http://www.website.com
Description: Displays contact box in sidebar
Version: 1.0
Author: JM
Author URI: N/A
*/
// use widgets_init action hook to execute custom function
add_action( 'widgets_init', 'jm_box_widget' );
//register our widget
function jm_box_widget() {
register_widget( 'jm_box_widget_my_info' );
}
//boj_widget_my_info class
class jm_box_widget_my_info extends WP_Widget {
//process the new widget
function jm_box_widget_my_info() {
$widget_ops = array(
'classname' => 'jm_box_widget_class',
'description' => 'Sidebar Box Widget.'
);
$this->WP_Widget( 'jm_box_widget_my_info', 'Box Widget', $widget_ops );
}
//build the widget settings form
function form($instance) {
$defaults = array( 'title' => 'Box Page Widget', 'description' => '', 'boxtype' => '' );
$instance = wp_parse_args( (array) $instance, $defaults );
$title = $instance['title'];
$description = $instance['description'];
$boxtype = $instance['boxtype'];
?>
<p>Title: <input class="widefat" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /></p>
<p>Description: <textarea class="widefat" name="<?php echo $this->get_field_name( 'description' ); ?>" / ><?php echo esc_attr( $description ); ?></textarea></p>
<p>Sex:
<select id="<?php echo $this->get_field_id( 'boxtype' ); ?>" name="<?php echo $this->get_field_name( 'boxtype' ); ?>" class="widefat" style="width:100%;">
<option <?php if ( 'box1' == $instance['format'] ) echo 'selected="selected"'; ?> value="box1">box1</option>
<option <?php if ( 'box2' == $instance['format'] ) echo 'selected="selected"'; ?> value="box2">box2</option>
</select>
</p>
<?php
}
//save the widget settings
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['description'] = strip_tags( $new_instance['description'] );
$instance['boxtype'] = ( $new_instance['boxtype'] );
return $instance;
}
//display the widget
function widget($args, $instance) {
extract($args);
echo $before_widget;
$title = apply_filters( 'widget_title', $instance['title'] );
$description = empty( $instance['description'] ) ? ' ' : $instance['description'];
$boxtype = empty( $instance['boxtype'] ) ? ' ' : $instance['boxtype'];
echo '<div class="sidebar-box" id="' . $boxtype . '" onmouseover="this.style.cursor=\'pointer\'" onmouseup="window.location=\'' . $boxtype . '\'">
<h3>' . $title . '</h3>
<p>' . $description . '</p>
</div>';
echo $after_widget;
}
}
?>
I can't for the life of me workout why it's not saving.
Any help would be greatly appreciated.
Thanks,
James
Somewhere along the line you must have changed $instance['format'] to $instance['boxtype'] but not in the form. The options need changing.
<option <?php if ('box1' == $boxtype )

Override widget in function WordPress

Im trying to override the text widget in WordPress. My code looks like this:
class WP_Widget_Text_Custom 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 WP_Widget_Calendar( $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 );
echo $before_widget;
if ( !empty( $title ) ) { echo $before_title . $title . $after_title; } ?>
<div class="textwidget test"><?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?></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'];
else
$instance['text'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text']) ) ); // 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' => '' ) );
$title = strip_tags($instance['title']);
$text = esc_textarea($instance['text']);
?>
<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>
<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
}
}
function custom_register_widgets() {
register_widget( 'WP_Widget_Text_Custom' );
}
add_action( 'widgets_init', 'custom_register_widgets' );
Im getting the following error message:
*function WP_Widget::widget() must be over-ridden in a sub-class.*
I have copied the WP_Widget_Text from default-widgets.php to functions.php and added _Custom in class name.
Why am I getting this error and how do I fix it?
You might try changing WP_Widget_Calendar to be widget.

Parse error with theme wordpress

I've developed a local site with wordpress and the theme Lugada.
All is OK on local. I've transfered all data on ovh.
When I want to see what is done I get the error:
Parse error: syntax error, unexpected T_STRING in
/homez.705/cadeauxd/www/wp-content/themes/lugada/include/widget.php on
line 1
When I add empty rows at the beginning it's the same thing: on line 1
Here's the file :
<?php
class RecentPost_Widget extends WP_Widget {
/* Register widget with WordPress. */
public function __construct() {
parent::__construct(
'recentpost_widget', // Base ID
'(Lugada) Recent Post with Thumbnail', // Name
array( 'description' => __( 'lugada recent post with post-thumbnail support widget.', 'lugada' ), ) // Args
);
}
/* Front-end display of widget. */
public function widget( $args, $instance ) {
extract( $args );
$title = apply_filters( 'widget_title', $instance['title'] );
$rcnumber = $instance['rcnumber'] ;
echo $before_widget;
if ( ! empty( $title ) )
echo $before_title . $title . $after_title;
?>
<?php
echo '<ul>';
echo lugada_display_recent_posts($rcnumber);
echo '</ul>';?>
<?php
echo $after_widget;
}
/* Sanitize widget form values as they are saved. */
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['rcnumber'] = strip_tags( $new_instance['rcnumber'] );
return $instance;
}
/* Back-end widget form. */
public function form( $instance ) {
if ( $instance ) {
$title = esc_attr( $instance[ 'title' ] );
$rcnumber = esc_attr( $instance[ 'rcnumber' ] );
}
else {
$title = __( 'Recent post', 'lugada' );
$rcnumber = __( '5', 'lugada' );
}
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:','lugada' ); ?></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( 'rcnumber' ); ?>"><?php _e( 'Number of recent post to show:','lugada' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'rcnumber' ); ?>" name="<?php echo $this->get_field_name( 'rcnumber' ); ?>" type="text" value="<?php echo $rcnumber; ?>" />
</p>
<?php
}
} // class RecentPost_Widget
class RandomPost_Widget extends WP_Widget {
/* Register widget with WordPress. */
public function __construct() {
parent::__construct(
'randompost_widget', // Base ID
'(Lugada) Random Post', // Name
array( 'description' => __( 'lugada random post widget.', 'lugada' ), ) // Args
);
}
/* Front-end display of widget. */
public function widget( $args, $instance ) {
extract( $args );
$title = apply_filters( 'widget_title', $instance['title'] );
$rndnumber = $instance['rndnumber'] ;
echo $before_widget;
if ( ! empty( $title ) )
echo $before_title . $title . $after_title;
?>
<?php
echo '<ul>';
echo lugada_display_random_posts($rndnumber);
echo '</ul>';?>
<?php
echo $after_widget;
}
/* Sanitize widget form values as they are saved. */
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['rndnumber'] = strip_tags( $new_instance['rndnumber'] );
return $instance;
}
/* Back-end widget form. */
public function form( $instance ) {
if ( $instance ) {
$title = esc_attr( $instance[ 'title' ] );
$rndnumber = esc_attr( $instance[ 'rndnumber' ] );
}
else {
$title = __( 'Random post', 'lugada' );
$rndnumber = __( '5', 'lugada' );
}
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:','lugada' ); ?></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( 'rndnumber' ); ?>"><?php _e( 'Number of random post to show:','lugada' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'rndnumber' ); ?>" name="<?php echo $this->get_field_name( 'rndnumber' ); ?>" type="text" value="<?php echo $rndnumber; ?>" />
</p>
<?php
}
} // class RandomPost_Widget
?>
That error usually means that you've got an unclosed string somewhere; the stated line number is usually not meaningful. Also check for things like unpaired parentheses or brackets, and places where you think you're writing in either HTML or PHP but you're actually writing in the other one.

How to add fields to the widget options in wordpress?

I wrote my first custom wordpress plugin. It is basically a copy of the default Recent Posts plugin (that comes out of the box), and then I am adding a filter to only get a certain post category. Originally, I just hardcoded this, but I figured I would just add a widget option that the user can change. This required adding an additional field in 'function form()'. I basically just copied and pasted the input field for the "title" text box (and then added the appropriate code for the new field - again copying and pastying from title). After I did this, the field showed up just fine, but I could the option would not save when clicking Save (the field just wipes out each time). Basically, the field is not posting properly (or something along those lines). My first question is, where are these fields stored? Also, am I supposed to be registering the field somewhere?
The code is below... The Category field is what I am trying to add. Please advise. Thanks.
<?php
/**
* Recent_Posts widget class
*
* #since 2.8.0
*/
class custom_RecentPostsByCategory extends WP_Widget {
function __construct() {
$widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "The most recent posts on your site (by Category)") );
parent::__construct('recent-posts', __('Custom: Recent Posts'), $widget_ops);
$this->alt_option_name = '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('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(array('posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true, 'category_name' => $instance['cat']));
if ($r->have_posts()) :
?>
<?php echo $before_widget; ?>
<?php if ( $title ) echo $before_title . $title . $after_title; ?>
<ul class="twitter-list">
<?php while ($r->have_posts()) : $r->the_post(); ?>
<li class="twitter-item">
<?php if ( get_the_title() ) the_title(); else the_ID(); ?><br/>
<?php the_time("F j, Y"); ?>
</li>
<!--<li><?php if ( get_the_title() ) the_title(); else the_ID(); ?></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('widget_recent_posts', $cache, 'widget');
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['cat'] = strip_tags($new_instance['cat']);
$instance['number'] = (int) $new_instance['number'];
$this->flush_widget_cache();
$alloptions = wp_cache_get( 'alloptions', 'options' );
if ( isset($alloptions['widget_recent_entries']) )
delete_option('widget_recent_entries');
return $instance;
}
function flush_widget_cache() {
wp_cache_delete('widget_recent_posts', 'widget');
}
function form( $instance ) {
$title = isset($instance['title']) ? esc_attr($instance['title']) : '';
$cat = isset($instance['cat']) ? esc_attr($instance['cat']) : '';
$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('cat'); ?>"><?php _e('Category:'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('cat'); ?>" name="<?php echo $this->get_field_name('cat'); ?>" type="text" value="<?php echo $cat; ?>" /></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
}
}
function wpzoom_register_rpa_widget() {
register_widget('custom_RecentPostsByCategory');
}
add_action('widgets_init', 'wpzoom_register_rpa_widget');
?>
You have to use unique id base for Widgets.
Change
parent::__construct('recent-posts', __('Custom: Recent Posts'), $widget_ops);
To
parent::__construct('recent-posts-custom', __('Custom: Recent Posts'), $widget_ops);

Resources