Make WordPress Core


Ignore:
Timestamp:
01/04/2008 11:34:33 PM (19 years ago)
Author:
ryan
Message:

Widget admin redesign from mdawaffe. see #5583

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/widgets.php

    r6436 r6556  
    33/* Global Variables */
    44
    5 global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_styles, $wp_registered_widget_defaults;
     5global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls;
    66
    77$wp_registered_sidebars = array();
    88$wp_registered_widgets = array();
    99$wp_registered_widget_controls = array();
    10 $wp_registered_widget_styles = array();
    11 $wp_register_widget_defaults = false;
    1210
    1311/* Template tags & API functions */
     
    9694
    9795function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) {
    98 
    99         global $wp_registered_widgets, $wp_register_widget_defaults;
     96        global $wp_registered_widgets;
    10097
    10198        if ( empty($output_callback) ) {
     
    114111        $widget = array_merge($widget, $options);
    115112
    116         if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || !$wp_register_widget_defaults) )
     113        if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) )
    117114                $wp_registered_widgets[$id] = $widget;
     115}
     116
     117function wp_widget_description( $id ) {
     118        if ( !is_scalar($id) )
     119                return;
     120
     121        global $wp_registered_widgets;
     122
     123        if ( isset($wp_registered_widgets[$id]['description']) )
     124                return wp_specialchars( $wp_registered_widgets[$id]['description'] );
    118125}
    119126
     
    150157}
    151158
     159/* $options: height, width, id_base
     160 *   height: never used
     161 *   width:  width of fully expanded control form.  Try hard to use the default width.
     162 *   id_base: for widgets which allow multiple instances (such as the text widget), an id_base must be provided.
     163 *            the widget id will ennd up looking like {$id_base}-{$unique_number}
     164 */
    152165function wp_register_widget_control($id, $name, $control_callback, $options = array()) {
    153         global $wp_registered_widget_controls, $wp_register_widget_defaults;
     166        global $wp_registered_widget_controls;
    154167
    155168        if ( empty($control_callback) ) {
     
    158171        }
    159172
    160         if ( isset($wp_registered_widget_controls[$id]) && $wp_register_widget_defaults )
     173        if ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) )
    161174                return;
    162175
    163         $defaults = array('width' => 300, 'height' => 200);
     176        $defaults = array('width' => 250, 'height' => 200 ); // height is never used
    164177        $options = wp_parse_args($options, $defaults);
    165178        $options['width'] = (int) $options['width'];
    166179        $options['height'] = (int) $options['height'];
    167         $options['width'] = $options['width'] > 90 ? $options['width'] + 60 : 360;
    168         $options['height'] = $options['height'] > 60 ? $options['height'] + 40 : 240;
    169180
    170181        $widget = array(
     
    235246}
    236247
     248/* @return mixed false if widget is not active or id of sidebar in which the widget is active
     249 */
    237250function is_active_widget($callback) {
    238251        global $wp_registered_widgets;
     
    240253        $sidebars_widgets = wp_get_sidebars_widgets(false);
    241254
    242         if ( is_array($sidebars_widgets) ) foreach ( $sidebars_widgets as $widgets )
     255        if ( is_array($sidebars_widgets) ) foreach ( $sidebars_widgets as $sidebar => $widgets )
    243256                if ( is_array($widgets) ) foreach ( $widgets as $widget )
    244257                        if ( $wp_registered_widgets[$widget]['callback'] == $callback )
    245                                 return true;
     258                                return $sidebar;
    246259
    247260        return false;
     
    388401        $exclude = attribute_escape( $options['exclude'] );
    389402?>
    390                         <p><label for="pages-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="pages-title" name="pages-title" type="text" value="<?php echo $title; ?>" /></label></p>
    391                         <p><label for="pages-sortby"><?php _e( 'Sort by:' ); ?>
    392                                 <select name="pages-sortby" id="pages-sortby">
     403                <p><label for="pages-title"><?php _e('Title:'); ?> <input class="widefat" id="pages-title" name="pages-title" type="text" value="<?php echo $title; ?>" /></label></p>
     404                <p>
     405                        <label for="pages-sortby"><?php _e( 'Sort by:' ); ?>
     406                                <select name="pages-sortby" id="pages-sortby" class="widefat">
    393407                                        <option value="post_title"<?php selected( $options['sortby'], 'post_title' ); ?>><?php _e('Page title'); ?></option>
    394408                                        <option value="menu_order"<?php selected( $options['sortby'], 'menu_order' ); ?>><?php _e('Page order'); ?></option>
    395409                                        <option value="ID"<?php selected( $options['sortby'], 'ID' ); ?>><?php _e( 'Page ID' ); ?></option>
    396                                 </select></label></p>
    397                         <p><label for="pages-exclude"><?php _e( 'Exclude:' ); ?> <input type="text" value="<?php echo $exclude; ?>" name="pages-exclude" id="pages-exclude" style="width: 180px;" /></label><br />
    398                         <small><?php _e( 'Page IDs, separated by commas.' ); ?></small></p>
    399                         <input type="hidden" id="pages-submit" name="pages-submit" value="1" />
     410                                </select>
     411                        </label>
     412                </p>
     413                <p>
     414                        <label for="pages-exclude"><?php _e( 'Exclude:' ); ?> <input type="text" value="<?php echo $exclude; ?>" name="pages-exclude" id="pages-exclude" class="widefat" /></label>
     415                        <br />
     416                        <small><?php _e( 'Page IDs, separated by commas.' ); ?></small>
     417                </p>
     418                <input type="hidden" id="pages-submit" name="pages-submit" value="1" />
    400419<?php
    401420}
     
    464483        $title = attribute_escape($options['title']);
    465484?>
    466                         <p><label for="archives-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="archives-title" name="archives-title" type="text" value="<?php echo $title; ?>" /></label></p>
    467                         <p style="text-align:right;margin-right:40px;"><label for="archives-count"><?php _e('Show post counts'); ?> <input class="checkbox" type="checkbox" <?php echo $count; ?> id="archives-count" name="archives-count" /></label></p>
    468                         <p style="text-align:right;margin-right:40px;"><label for="archives-dropdown"><?php _e('Display as a drop down'); ?> <input class="checkbox" type="checkbox" <?php echo $dropdown; ?> id="archives-dropdown" name="archives-dropdown" /></label></p>
     485                        <p><label for="archives-title"><?php _e('Title:'); ?> <input class="widefat" id="archives-title" name="archives-title" type="text" value="<?php echo $title; ?>" /></label></p>
     486                        <p>
     487                                <label for="archives-count"><input class="checkbox" type="checkbox" <?php echo $count; ?> id="archives-count" name="archives-count" /> <?php _e('Show post counts'); ?></label>
     488                                <br />
     489                                <label for="archives-dropdown"><input class="checkbox" type="checkbox" <?php echo $dropdown; ?> id="archives-dropdown" name="archives-dropdown" /> <?php _e('Display as a drop down'); ?></label>
     490                        </p>
    469491                        <input type="hidden" id="archives-submit" name="archives-submit" value="1" />
    470492<?php
     
    500522        $title = attribute_escape($options['title']);
    501523?>
    502                         <p><label for="meta-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="meta-title" name="meta-title" type="text" value="<?php echo $title; ?>" /></label></p>
     524                        <p><label for="meta-title"><?php _e('Title:'); ?> <input class="widefat" id="meta-title" name="meta-title" type="text" value="<?php echo $title; ?>" /></label></p>
    503525                        <input type="hidden" id="meta-submit" name="meta-submit" value="1" />
    504526<?php
     
    528550        $title = attribute_escape($options['title']);
    529551?>
    530                         <p><label for="calendar-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="calendar-title" name="calendar-title" type="text" value="<?php echo $title; ?>" /></label></p>
     552                        <p><label for="calendar-title"><?php _e('Title:'); ?> <input class="widefat" id="calendar-title" name="calendar-title" type="text" value="<?php echo $title; ?>" /></label></p>
    531553                        <input type="hidden" id="calendar-submit" name="calendar-submit" value="1" />
    532554<?php
    533555}
    534556
    535 function wp_widget_text($args, $number = 1) {
    536         extract($args);
     557// See large comment section at end of this file
     558function wp_widget_text($args, $widget_args = 1) {
     559        extract( $args, EXTR_SKIP );
     560        if ( is_numeric($widget_args) )
     561                $widget_args = array( 'number' => $widget_args );
     562        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     563        extract( $widget_args, EXTR_SKIP );
     564
    537565        $options = get_option('widget_text');
     566        if ( !isset($options[$number]) )
     567                return;
     568
    538569        $title = $options[$number]['title'];
    539570        $text = apply_filters( 'widget_text', $options[$number]['text'] );
     
    546577}
    547578
    548 function wp_widget_text_control($number) {
    549         $options = $newoptions = get_option('widget_text');
     579function wp_widget_text_control($widget_args) {
     580        global $wp_registered_widgets;
     581        static $updated = false;
     582
     583        if ( is_numeric($widget_args) )
     584                $widget_args = array( 'number' => $widget_args );
     585        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     586        extract( $widget_args, EXTR_SKIP );
     587
     588        $options = get_option('widget_text');
    550589        if ( !is_array($options) )
    551                 $options = $newoptions = array();
    552         if ( $_POST["text-submit-$number"] ) {
    553                 $newoptions[$number]['title'] = strip_tags(stripslashes($_POST["text-title-$number"]));
    554                 $newoptions[$number]['text'] = stripslashes($_POST["text-text-$number"]);
    555                 if ( !current_user_can('unfiltered_html') )
    556                         $newoptions[$number]['text'] = stripslashes(wp_filter_post_kses($newoptions[$number]['text']));
    557         }
    558         if ( $options != $newoptions ) {
    559                 $options = $newoptions;
     590                $options = array();
     591
     592        if ( !$updated && !empty($_POST['sidebar']) ) {
     593                $sidebar = (string) $_POST['sidebar'];
     594
     595                $sidebars_widgets = wp_get_sidebars_widgets();
     596                if ( isset($sidebars_widgets[$sidebar]) )
     597                        $this_sidebar =& $sidebars_widgets[$sidebar];
     598                else
     599                        $this_sidebar = array();
     600
     601                foreach ( $this_sidebar as $_widget_id ) {
     602                        if ( 'wp_widget_text' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) {
     603                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
     604                                unset($options[$widget_number]);
     605                        }
     606                }
     607
     608                foreach ( (array) $_POST['widget-text'] as $widget_number => $widget_text ) {
     609                        $title = strip_tags(stripslashes($widget_text['title']));
     610                        if ( current_user_can('unfiltered_html') )
     611                                $text = stripslashes( $widget_text['text'] );
     612                        else
     613                                $text = stripslashes(wp_filter_post_kses( $widget_text['text'] ));
     614                        $options[$widget_number] = compact( 'title', 'text' );
     615                }
     616
    560617                update_option('widget_text', $options);
    561         }
    562         $title = attribute_escape($options[$number]['title']);
    563         $text = format_to_edit($options[$number]['text']);
    564 ?>
    565                         <input style="width: 450px;" id="text-title-<?php echo $number; ?>" name="text-title-<?php echo $number; ?>" type="text" value="<?php echo $title; ?>" />
    566                         <textarea style="width: 450px; height: 280px;" id="text-text-<?php echo $number; ?>" name="text-text-<?php echo $number; ?>"><?php echo $text; ?></textarea>
    567                         <input type="hidden" id="text-submit-<?php echo "$number"; ?>" name="text-submit-<?php echo "$number"; ?>" value="1" />
    568 <?php
    569 }
    570 
    571 function wp_widget_text_setup() {
    572         $options = $newoptions = get_option('widget_text');
    573         if ( isset($_POST['text-number-submit']) ) {
    574                 $number = (int) $_POST['text-number'];
    575                 if ( $number > 9 ) $number = 9;
    576                 if ( $number < 1 ) $number = 1;
    577                 $newoptions['number'] = $number;
    578         }
    579         if ( $options != $newoptions ) {
    580                 $options = $newoptions;
    581                 update_option('widget_text', $options);
    582                 wp_widget_text_register($options['number']);
    583         }
    584 }
    585 
    586 function wp_widget_text_page() {
    587         $options = get_option('widget_text');
    588 ?>
    589         <div class="wrap">
    590                 <form method="POST">
    591                         <h2><?php _e('Text Widgets'); ?></h2>
    592                         <p style="line-height: 30px;"><?php _e('How many text widgets would you like?'); ?>
    593                         <select id="text-number" name="text-number" value="<?php echo $options['number']; ?>">
    594 <?php for ( $i = 1; $i < 10; ++$i ) echo "<option value='$i' ".($options['number']==$i ? "selected='selected'" : '').">$i</option>"; ?>
    595                         </select>
    596                         <span class="submit"><input type="submit" name="text-number-submit" id="text-number-submit" value="<?php echo attribute_escape(__('Save')); ?>" /></span></p>
    597                 </form>
    598         </div>
     618                $updated = true;
     619        }
     620
     621        if ( -1 == $number ) {
     622                $title = '';
     623                $text = '';
     624                $number = '%i%';
     625        } else {
     626                $title = attribute_escape($options[$number]['title']);
     627                $text = format_to_edit($options[$number]['text']);
     628        }
     629?>
     630                <p>
     631                        <input class="widefat" id="text-title-<?php echo $number; ?>" name="widget-text[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" />
     632                        <textarea class="widefat" rows="16" cols="20" id="text-text-<?php echo $number; ?>" name="widget-text[<?php echo $number; ?>][text]"><?php echo $text; ?></textarea>
     633                        <input type="hidden" id="text-submit-<?php echo $number; ?>" name="text-submit-<?php echo $number; ?>" value="1" />
     634                </p>
    599635<?php
    600636}
     
    602638function wp_widget_text_register() {
    603639        $options = get_option('widget_text');
    604         $number = $options['number'];
    605         if ( $number < 1 ) $number = 1;
    606         if ( $number > 9 ) $number = 9;
    607         $dims = array('width' => 460, 'height' => 350);
    608         $class = array('classname' => 'widget_text');
    609         for ($i = 1; $i <= 9; $i++) {
    610                 $name = sprintf(__('Text %d'), $i);
    611                 $id = "text-$i"; // Never never never translate an id
    612                 wp_register_sidebar_widget($id, $name, $i <= $number ? 'wp_widget_text' : /* unregister */ '', $class, $i);
    613                 wp_register_widget_control($id, $name, $i <= $number ? 'wp_widget_text_control' : /* unregister */ '', $dims, $i);
    614         }
    615         add_action('sidebar_admin_setup', 'wp_widget_text_setup');
    616         add_action('sidebar_admin_page', 'wp_widget_text_page');
    617 }
    618 
    619 function wp_widget_categories($args, $number = 1) {
    620         extract($args);
     640        $widget_ops = array('classname' => 'widget_text', 'description' => __('Arbitrary text or HTML'));
     641        $control_ops = array('width' => 460, 'height' => 350, 'id_base' => 'text');
     642        $name = __('Text');
     643
     644        // If there are none, we register the widget's existance with a generic template
     645        if ( !$options ) {
     646                wp_register_sidebar_widget( 'text-1', $name, 'wp_widget_text', $widget_ops, array( 'number' => -1 ) );
     647                wp_register_widget_control( 'text-1', $name, 'wp_widget_text_control', $control_ops, array( 'number' => -1 ) );
     648        }
     649
     650        foreach ( array_keys($options) as $o ) {
     651                // Old widgets can have null values for some reason
     652                if ( !isset($options[$o]['title']) || !isset($options[$o]['text']) )
     653                        continue;
     654                $id = "text-$o"; // Never never never translate an id
     655                wp_register_sidebar_widget($id, $name, 'wp_widget_text', $widget_ops, array( 'number' => $o ));
     656                wp_register_widget_control($id, $name, 'wp_widget_text_control', $control_ops, array( 'number' => $o ));
     657        }
     658}
     659
     660// See large comment section at end of this file
     661function wp_widget_categories($args, $widget_args = 1) {
     662        extract($args, EXTR_SKIP);
     663        if ( is_numeric($widget_args) )
     664                $widget_args = array( 'number' => $widget_args );
     665        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     666        extract($widget_args, EXTR_SKIP);
     667
    621668        $options = get_option('widget_categories');
     669        if ( !isset($options[$number]) )
     670                return;
    622671
    623672        $c = $options[$number]['count'] ? '1' : '0';
     
    636685?>
    637686
    638 <script type='text/javascript'><!--
     687<script type='text/javascript'>
     688/* <![CDATA[ */
    639689    var dropdown = document.getElementById("cat");
    640690    function onCatChange() {
     
    644694    }
    645695    dropdown.onchange = onCatChange;
    646 --></script>
     696/* ]]> */
     697</script>
    647698
    648699<?php
     
    658709}
    659710
    660 function wp_widget_categories_control( $number ) {
    661         $options = $newoptions = get_option('widget_categories');
    662 
    663         if ( !is_array( $options ) ) {
    664                 $options = $newoptions = get_option( 'widget_categories' );
    665         }
    666 
    667         if ( $_POST['categories-submit-' . $number] ) {
    668                 $newoptions[$number]['count'] = isset($_POST['categories-count-' . $number]);
    669                 $newoptions[$number]['hierarchical'] = isset($_POST['categories-hierarchical-' . $number]);
    670                 $newoptions[$number]['dropdown'] = isset($_POST['categories-dropdown-' . $number]);
    671                 $newoptions[$number]['title'] = strip_tags(stripslashes($_POST['categories-title-' . $number]));
    672         }
    673 
    674         if ( $options != $newoptions ) {
    675                 $options = $newoptions;
     711function wp_widget_categories_control( $widget_args ) {
     712        global $wp_registered_widgets;
     713        static $updated = false;
     714
     715        if ( is_numeric($widget_args) )
     716                $widget_args = array( 'number' => $widget_args );
     717        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     718        extract($widget_args, EXTR_SKIP);
     719
     720        $options = get_option('widget_categories');
     721
     722        if ( !is_array( $options ) )
     723                $options = array();
     724
     725        if ( !$updated && !empty($_POST['sidebar']) ) {
     726                $sidebar = (string) $_POST['sidebar'];
     727               
     728                $sidebars_widgets = wp_get_sidebars_widgets();
     729                if ( isset($sidebars_widgets[$sidebar]) )
     730                        $this_sidebar =& $sidebars_widgets[$sidebar];
     731                else
     732                        $this_sidebar = array();
     733               
     734                foreach ( $this_sidebar as $_widget_id ) {
     735                        if ( 'wp_widget_categories' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) {
     736                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
     737                                unset($options[$widget_number]);
     738                        }   
     739                }
     740
     741                foreach ( (array) $_POST['widget-categories'] as $widget_number => $widget_cat ) {
     742                        $title = trim(strip_tags(stripslashes($widget_cat['title'])));
     743                        $count = isset($widget_cat['count']);
     744                        $hierarchical = isset($widget_cat['hierarchical']);
     745                        $dropdown = isset($widget_cat['dropdown']);
     746                        $options[$widget_number] = compact( 'title', 'count', 'hierarchical', 'dropdown' );
     747                }
     748
    676749                update_option('widget_categories', $options);
    677         }
    678 
    679         $title = attribute_escape( $options[$number]['title'] );
    680 ?>
    681                         <p><label for="categories-title-<?php echo $number; ?>">
    682                                 <?php _e( 'Title:' ); ?> <input style="width:300px" id="categories-title-<?php echo $number; ?>" name="categories-title-<?php echo $number; ?>" type="text" value="<?php echo $title; ?>" />
    683                         </label></p>
    684 
    685                         <p><label for="categories-dropdown-<?php echo $number; ?>">
    686                                 <input type="checkbox" class="checkbox" id="categories-dropdown-<?php echo $number; ?>" name="categories-dropdown-<?php echo $number; ?>"<?php echo $options[$number]['dropdown'] ? ' checked="checked"' : ''; ?> /> <?php _e( 'Show as dropdown' ); ?>
    687                         </label></p>
    688 
    689                         <p><label for="categories-count-<?php echo $number; ?>">
    690                                 <input type="checkbox" class="checkbox" id="categories-count-<?php echo $number; ?>" name="categories-count-<?php echo $number; ?>"<?php echo $options[$number]['count'] ? ' checked="checked"' : ''; ?> /> <?php _e( 'Show post counts' ); ?>
    691                         </label></p>
    692 
    693                         <p><label for="categories-hierarchical-<?php echo $number; ?>">
    694                                 <input type="checkbox" class="checkbox" id="categories-hierarchical-<?php echo $number; ?>" name="categories-hierarchical-<?php echo $number; ?>"<?php echo $options[$number]['hierarchical'] ? ' checked="checked"' : ''; ?> /> <?php _e( 'Show hierarchy' ); ?>
    695                         </label></p>
     750                $updated = true;
     751        }
     752
     753        if ( -1 == $number ) {
     754                $title = '';
     755                $count = false;
     756                $hierarchical = false;
     757                $dropdown = false;
     758                $number = '%i%';
     759        } else {
     760                $title = attribute_escape( $options[$number]['title'] );
     761                $count = (bool) $options[$number]['count'];
     762                $hierarchical = (bool) $options[$number]['hierarchical'];
     763                $dropdown = (bool) $options[$number]['dropdown'];
     764        }
     765?>
     766                        <p>
     767                                <label for="categories-title-<?php echo $number; ?>">
     768                                        <?php _e( 'Title:' ); ?>
     769                                        <input class="widefat" id="categories-title-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" />
     770                                </label>
     771                        </p>
     772
     773                        <p>
     774                                <label for="categories-dropdown-<?php echo $number; ?>">
     775                                        <input type="checkbox" class="checkbox" id="categories-dropdown-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][dropdown]"<?php checked( $dropdown, true ); ?> />
     776                                        <?php _e( 'Show as dropdown' ); ?>
     777                                </label>
     778                                <br />
     779                                <label for="categories-count-<?php echo $number; ?>">
     780                                        <input type="checkbox" class="checkbox" id="categories-count-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][count]"<?php checked( $count, true ); ?> />
     781                                        <?php _e( 'Show post counts' ); ?>
     782                                </label>
     783                                <br />
     784                                <label for="categories-hierarchical-<?php echo $number; ?>">
     785                                        <input type="checkbox" class="checkbox" id="categories-hierarchical-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][hierarchical]"<?php checked( $hierarchical, true ); ?> />
     786                                        <?php _e( 'Show hierarchy' ); ?>
     787                                </label>
     788                        </p>
    696789
    697790                        <input type="hidden" id="categories-submit-<?php echo $number; ?>" name="categories-submit-<?php echo $number; ?>" value="1" />
     
    699792}
    700793
    701 function wp_widget_categories_setup() {
    702         $options = $newoptions = get_option( 'widget_categories' );
    703 
    704         if ( isset( $_POST['categories-number-submit'] ) ) {
    705                 $number = (int) $_POST['categories-number'];
    706 
    707                 if ( $number > 9 ) {
    708                         $number = 9;
    709                 } elseif ( $number < 1 ) {
    710                         $number = 1;
    711                 }
    712 
    713                 $newoptions['number'] = $number;
    714         }
    715 
    716         if ( $newoptions != $options ) {
    717                 $options = $newoptions;
    718                 update_option( 'widget_categories', $options );
    719                 wp_widget_categories_register( $options['number'] );
    720         }
    721 }
    722 
    723 function wp_widget_categories_page() {
     794function wp_widget_categories_register() {
    724795        $options = get_option( 'widget_categories' );
    725 ?>
    726         <div class="wrap">
    727                 <form method="post">
    728                         <h2><?php _e( 'Categories Widgets' ); ?></h2>
    729                         <p style="line-height: 30px;"><?php _e( 'How many categories widgets would you like?' ); ?>
    730                                 <select id="categories-number" name="categories-number" value="<?php echo attribute_escape( $options['number'] ); ?>">
    731                                         <?php
    732                                                 for ( $i = 1; $i < 10; $i++ ) {
    733                                                         echo '<option value="' . $i . '"' . ( $i == $options['number'] ? ' selected="selected"' : '' ) . '>' . $i . "</option>\n";
    734                                                 }
    735                                         ?>
    736                                 </select>
    737                                 <span class="submit">
    738                                         <input type="submit" value="<?php echo attribute_escape( __( 'Save' ) ); ?>" id="categories-number-submit" name="categories-number-submit" />
    739                                 </span>
    740                         </p>
    741                 </form>
    742         </div>
    743 <?php
     796        if ( isset($options['title']) )
     797                $options = wp_widget_categories_upgrade();
     798
     799        $widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "A list or dropdown of categories" ) );
     800
     801        $name = __( 'Categories' );
     802
     803        // If there are none, we register the widget's existance with a generic template
     804        if ( !$options ) {
     805                wp_register_sidebar_widget( 'categories-1', $name, 'wp_widget_categories', $widget_ops, array( 'number' => -1 ) );
     806                wp_register_widget_control( 'categories-1', $name, 'wp_widget_categories_control', array( 'id_base' => 'categories' ), array( 'number' => -1 ) );
     807        }
     808
     809        foreach ( array_keys($options) as $o ) {
     810                // Old widgets can have null values for some reason
     811                if ( !isset($options[$o]['title']) )
     812                        continue;
     813                $id = "categories-$o";
     814                wp_register_sidebar_widget( $id, $name, 'wp_widget_categories', $widget_ops, array( 'number' => $o ) );
     815                wp_register_widget_control( $id, $name, 'wp_widget_categories_control', array( 'id_base' => 'categories' ), array( 'number' => $o ) );
     816        }
     817
    744818}
    745819
     
    747821        $options = get_option( 'widget_categories' );
    748822
    749         $newoptions = array( 'number' => 1, 1 => $options );
     823        if ( !isset( $options['title'] ) )
     824                return $options;
     825
     826        $newoptions = array( 1 => $options );
    750827
    751828        update_option( 'widget_categories', $newoptions );
     
    765842        }
    766843
    767         if ( isset( $_POST['categories-submit'] ) ) {
    768                 $_POST['categories-submit-1'] = $_POST['categories-submit'];
    769                 $_POST['categories-count-1'] = $_POST['categories-count'];
    770                 $_POST['categories-hierarchical-1'] = $_POST['categories-hierarchical'];
    771                 $_POST['categories-dropdown-1'] = $_POST['categories-dropdown'];
    772                 $_POST['categories-title-1'] = $_POST['categories-title'];
    773                 foreach ( $_POST as $k => $v )
    774                         if ( substr($k, -5) == 'order' )
    775                                 $_POST[$k] = str_replace('categories', 'categories-1', $v);
    776         }
    777 
    778844        return $newoptions;
    779 }
    780 
    781 function wp_widget_categories_register() {
    782         $options = get_option( 'widget_categories' );
    783         if ( !isset($options['number']) )
    784                 $options = wp_widget_categories_upgrade();
    785         $number = (int) $options['number'];
    786 
    787         if ( $number > 9 ) {
    788                 $number = 9;
    789         } elseif ( $number < 1 ) {
    790                 $number = 1;
    791         }
    792 
    793         $dims = array( 'width' => 350, 'height' => 170 );
    794         $class = array( 'classname' => 'widget_categories' );
    795 
    796         for ( $i = 1; $i <= 9; $i++ ) {
    797                 $name = sprintf( __( 'Categories %d' ), $i );
    798                 $id = 'categories-' . $i;
    799 
    800                 $widget_callback = ( $i <= $number ) ? 'wp_widget_categories' : '';
    801                 $control_callback = ( $i <= $number ) ? 'wp_widget_categories_control' : '';
    802 
    803                 wp_register_sidebar_widget( $id, $name, $widget_callback, $class, $i );
    804                 wp_register_widget_control( $id, $name, $control_callback, $dims, $i );
    805         }
    806 
    807         add_action( 'sidebar_admin_setup', 'wp_widget_categories_setup' );
    808         add_action( 'sidebar_admin_page', 'wp_widget_categories_page' );
    809845}
    810846
     
    862898                $number = 5;
    863899?>
    864                         <p><label for="recent-entries-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="recent-entries-title" name="recent-entries-title" type="text" value="<?php echo $title; ?>" /></label></p>
    865                         <p><label for="recent-entries-number"><?php _e('Number of posts to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-entries-number" name="recent-entries-number" type="text" value="<?php echo $number; ?>" /></label> <?php _e('(at most 15)'); ?></p>
     900
     901                        <p><label for="recent-entries-title"><?php _e('Title:'); ?> <input class="widefat" id="recent-entries-title" name="recent-entries-title" type="text" value="<?php echo $title; ?>" /></label></p>
     902                        <p>
     903                                <label for="recent-entries-number"><?php _e('Number of posts to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-entries-number" name="recent-entries-number" type="text" value="<?php echo $number; ?>" /></label>
     904                                <br />
     905                                <small><?php _e('(at most 15)'); ?></small>
     906                        </p>
    866907                        <input type="hidden" id="recent-entries-submit" name="recent-entries-submit" value="1" />
    867908<?php
     
    917958                $number = 5;
    918959?>
    919                         <p><label for="recent-comments-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="recent-comments-title" name="recent-comments-title" type="text" value="<?php echo $title; ?>" /></label></p>
    920                         <p><label for="recent-comments-number"><?php _e('Number of comments to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-comments-number" name="recent-comments-number" type="text" value="<?php echo $number; ?>" /></label> <?php _e('(at most 15)'); ?></p>
     960                        <p><label for="recent-comments-title"><?php _e('Title:'); ?> <input class="widefat" id="recent-comments-title" name="recent-comments-title" type="text" value="<?php echo $title; ?>" /></label></p>
     961                        <p>
     962                                <label for="recent-comments-number"><?php _e('Number of comments to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-comments-number" name="recent-comments-number" type="text" value="<?php echo $number; ?>" /></label>
     963                                <br />
     964                                <small><?php _e('(at most 15)'); ?></small>
     965                        </p>
    921966                        <input type="hidden" id="recent-comments-submit" name="recent-comments-submit" value="1" />
    922967<?php
     
    930975
    931976function wp_widget_recent_comments_register() {
    932         $dims = array('width' => 320, 'height' => 90);
    933         $class = array('classname' => 'widget_recent_comments');
    934         wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $class);
    935         wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control', $dims);
     977        $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) );
     978        wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $widget_ops);
     979        wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control');
    936980
    937981        if ( is_active_widget('wp_widget_recent_comments') )
     
    939983}
    940984
    941 function wp_widget_rss($args, $number = 1) {
    942         require_once(ABSPATH . WPINC . '/rss.php');
    943         extract($args);
     985// See large comment section at end of this file
     986function wp_widget_rss($args, $widget_args = 1) {
     987        extract($args, EXTR_SKIP);
     988        if ( is_numeric($widget_args) )
     989                $widget_args = array( 'number' => $widegt_args );
     990        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     991        extract($widget_args, EXTR_SKIP);
     992
    944993        $options = get_option('widget_rss');
    945         if ( isset($options['error']) && $options['error'] )
     994
     995        if ( !isset($options[$number]) )
    946996                return;
     997
     998        if ( isset($options[$number]['error']) && $options[$number]['error'] )
     999                return;
     1000
    9471001        $num_items = (int) $options[$number]['items'];
    9481002        $show_summary = $options[$number]['show_summary'];
     
    9531007        if ( empty($url) )
    9541008                return;
     1009
     1010        require_once(ABSPATH . WPINC . '/rss.php');
     1011
    9551012        $rss = fetch_rss($url);
    9561013        $link = clean_url(strip_tags($rss->channel['link']));
     
    10031060}
    10041061
    1005 function wp_widget_rss_control($number) {
    1006         $options = $newoptions = get_option('widget_rss');
    1007         if ( $_POST["rss-submit-$number"] ) {
    1008                 $newoptions[$number]['items'] = (int) $_POST["rss-items-$number"];
    1009                 $url = sanitize_url(strip_tags(stripslashes($_POST["rss-url-$number"])));
    1010                 $newoptions[$number]['title'] = trim(strip_tags(stripslashes($_POST["rss-title-$number"])));
    1011                 if ( $url !== $options[$number]['url'] ) {
    1012                         require_once(ABSPATH . WPINC . '/rss.php');
    1013                         $rss = fetch_rss($url);
    1014                         if ( is_object($rss) ) {
    1015                                 $newoptions[$number]['url'] = $url;
    1016                                 $newoptions[$number]['error'] = false;
    1017                         } else {
    1018                                 $newoptions[$number]['error'] = true;
    1019                                 $newoptions[$number]['url'] = wp_specialchars(__('Error: could not find an RSS or ATOM feed at that URL.'), 1);
     1062function wp_widget_rss_control($widget_args) {
     1063        global $wp_registered_widgets;
     1064        static $updated = false;
     1065
     1066        if ( is_numeric($widget_args) )
     1067                $widget_args = array( 'number' => $widget_args );
     1068        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     1069        extract($widget_args, EXTR_SKIP);
     1070
     1071        $options = get_option('widget_rss');
     1072        if ( !is_array($options) )
     1073                $options = array();
     1074
     1075        $urls = array();
     1076        foreach ( $options as $option )
     1077                if ( isset($option['url']) )
     1078                        $urls[$option['url']] = true;
     1079
     1080        if ( !$updated && !empty($_POST['sidebar']) ) {
     1081                $sidebar = (string) $_POST['sidebar'];
     1082
     1083                $sidebars_widgets = wp_get_sidebars_widgets();
     1084                if ( isset($sidebars_widgets[$sidebar]) )
     1085                        $this_sidebar =& $sidebars_widgets[$sidebar];
     1086                else
     1087                        $this_sidebar = array();
     1088       
     1089                foreach ( $this_sidebar as $_widget_id ) {
     1090                        if ( 'wp_widget_rss' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) {
     1091                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
     1092                                unset($options[$widget_number]);
    10201093                        }
    10211094                }
    1022         }
    1023         if ( $options != $newoptions ) {
    1024                 $options = $newoptions;
     1095
     1096                foreach( (array) $_POST['widget-rss'] as $widget_number => $widget_rss ) {
     1097                        $items = (int) $widget_rss['items'];
     1098                        if ( $items < 1 )
     1099                                $items = 10;
     1100                        $url = sanitize_url(strip_tags(stripslashes($widget_rss['url'])));
     1101                        $title = trim(strip_tags(stripslashes($widget_rss['title'])));
     1102
     1103                        if ( !isset($urls[$url]) ) {
     1104                                require_once(ABSPATH . WPINC . '/rss.php');
     1105                                $rss = fetch_rss($url);
     1106                                $error = false;
     1107                                if ( !is_object($rss) ) {
     1108                                        $url = wp_specialchars(__('Error: could not find an RSS or ATOM feed at that URL.'), 1);
     1109                                        $error = sprintf(__('Error in RSS %1$d'), $widget_number );
     1110                                }
     1111                        }
     1112                        $options[$widget_number] = compact( 'title', 'url', 'items', 'error' );
     1113                }
     1114
    10251115                update_option('widget_rss', $options);
    1026         }
    1027         $url = attribute_escape($options[$number]['url']);
    1028         $items = (int) $options[$number]['items'];
    1029         $title = attribute_escape($options[$number]['title']);
    1030         if ( empty($items) || $items < 1 ) $items = 10;
    1031 ?>
    1032                         <p style="text-align:center;"><?php _e('Enter the RSS feed URL here:'); ?></p>
    1033                         <input style="width: 400px;" id="rss-url-<?php echo "$number"; ?>" name="rss-url-<?php echo "$number"; ?>" type="text" value="<?php echo $url; ?>" />
    1034                         <p style="text-align:center;"><?php _e('Give the feed a title (optional):'); ?></p>
    1035                         <input style="width: 400px;" id="rss-title-<?php echo "$number"; ?>" name="rss-title-<?php echo "$number"; ?>" type="text" value="<?php echo $title; ?>" />
    1036                         <p style="text-align:center; line-height: 30px;"><?php _e('How many items would you like to display?'); ?> <select id="rss-items-<?php echo $number; ?>" name="rss-items-<?php echo $number; ?>"><?php for ( $i = 1; $i <= 10; ++$i ) echo "<option value='$i' ".($items==$i ? "selected='selected'" : '').">$i</option>"; ?></select></p>
    1037                         <input type="hidden" id="rss-submit-<?php echo "$number"; ?>" name="rss-submit-<?php echo $number; ?>" value="1" />
    1038 <?php
    1039 }
    1040 
    1041 function wp_widget_rss_setup() {
    1042         $options = $newoptions = get_option('widget_rss');
    1043         if ( isset($_POST['rss-number-submit']) ) {
    1044                 $number = (int) $_POST['rss-number'];
    1045                 if ( $number > 9 ) $number = 9;
    1046                 if ( $number < 1 ) $number = 1;
    1047                 $newoptions['number'] = $number;
    1048         }
    1049         if ( $options != $newoptions ) {
    1050                 $options = $newoptions;
    1051                 update_option('widget_rss', $options);
    1052                 wp_widget_rss_register($options['number']);
    1053         }
    1054 }
    1055 
    1056 function wp_widget_rss_page() {
    1057         $options = get_option('widget_rss');
    1058 ?>
    1059         <div class="wrap">
    1060                 <form method="POST">
    1061                         <h2><?php _e('RSS Feed Widgets'); ?></h2>
    1062                         <p style="line-height: 30px;"><?php _e('How many RSS widgets would you like?'); ?>
    1063                         <select id="rss-number" name="rss-number" value="<?php echo $options['number']; ?>">
    1064 <?php for ( $i = 1; $i < 10; ++$i ) echo "<option value='$i' ".($options['number']==$i ? "selected='selected'" : '').">$i</option>"; ?>
    1065                         </select>
    1066                         <span class="submit"><input type="submit" name="rss-number-submit" id="rss-number-submit" value="<?php echo attribute_escape(__('Save')); ?>" /></span></p>
    1067                 </form>
    1068         </div>
     1116                $updated = true;
     1117        }
     1118
     1119        if ( -1 == $number ) {
     1120                $title = '';
     1121                $url = '';
     1122                $items = 10;
     1123                $error = false;
     1124                $number = '%i%';
     1125        } else {
     1126                $title = attribute_escape($options[$number]['title']);
     1127                $url = attribute_escape($options[$number]['url']);
     1128                $items = (int) $options[$number]['items'];
     1129                if ( $items < 1 )
     1130                        $items = 10;
     1131                $error = $options[$number]['error'];
     1132        }
     1133
     1134?>
     1135                        <p>
     1136                                <label for="rss-url-<?php echo $number; ?>"><?php _e('Enter the RSS feed URL here:'); ?>
     1137                                        <input class="widefat" id="rss-url-<?php echo $number; ?>" name="widget-rss[<?php echo $number; ?>][url]" type="text" value="<?php echo $url; ?>" />
     1138                                </label>
     1139                        </p>
     1140                        <p>
     1141                                <label for="rss-title-<?php echo $number; ?>"><?php _e('Give the feed a title (optional):'); ?>
     1142                                        <input class="widefat" id="rss-title-<?php echo $number; ?>" name="widget-rss[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" />
     1143                                </label>
     1144                        </p>
     1145                        <p>
     1146                                <label for="rss-items-<?php echo $number; ?>"><?php _e('How many items would you like to display?'); ?>
     1147                                        <select id="rss-items-<?php echo $number; ?>" name="widget-rss[<?php echo $number; ?>][items]">
     1148                                                <?php
     1149                                                        for ( $i = 1; $i <= 10; ++$i )
     1150                                                                echo "<option value='$i' " . ( $items == $i ? "selected='selected'" : '' ) . ">$i</option>";
     1151                                                ?>
     1152                                        </select>
     1153                                </label>
     1154                        </p>
     1155                        <input type="hidden" id="rss-submit-<?php echo $number; ?>" name="rss-submit-<?php echo $number; ?>" value="1" />
    10691156<?php
    10701157}
     
    10721159function wp_widget_rss_register() {
    10731160        $options = get_option('widget_rss');
    1074         $number = $options['number'];
    1075         if ( $number < 1 ) $number = 1;
    1076         if ( $number > 9 ) $number = 9;
    1077         $dims = array('width' => 410, 'height' => 200);
    1078         $class = array('classname' => 'widget_rss');
    1079         for ($i = 1; $i <= 9; $i++) {
    1080                 $name = sprintf(__('RSS %d'), $i);
    1081                 $id = "rss-$i"; // Never never never translate an id
    1082                 wp_register_sidebar_widget($id, $name, $i <= $number ? 'wp_widget_rss' : /* unregister */ '', $class, $i);
    1083                 wp_register_widget_control($id, $name, $i <= $number ? 'wp_widget_rss_control' : /* unregister */ '', $dims, $i);
    1084         }
    1085         add_action('sidebar_admin_setup', 'wp_widget_rss_setup');
    1086         add_action('sidebar_admin_page', 'wp_widget_rss_page');
     1161        $widget_ops = array('classname' => 'widget_rss', 'description' => __( 'Entries from any RSS or Atom feed' ));
     1162        $control_ops = array('width' => 410, 'height' => 200, 'id_base' => 'rss');
     1163        $name = __('RSS');
     1164
     1165        // If there are none, we register the widget's existance with a generic template
     1166        if ( !$options ) {
     1167                wp_register_sidebar_widget( 'rss-1', $name, 'wp_widget_rss', $widget_ops, array( 'number' => -1 ) );
     1168                wp_register_widget_control( 'rss-1', $name, 'wp_widget_rss_control', $control_ops, array( 'number' => -1 ) );
     1169        }
     1170
     1171        foreach ( array_keys($options) as $o ) {
     1172                // Old widgets can have null values for some reason
     1173                if ( !isset($options[$o]['url']) || !isset($options[$o]['title']) || !isset($options[$o]['items']) )
     1174                        contine;
     1175                $id = "rss-$o"; // Never never never translate an id
     1176                wp_register_sidebar_widget($id, $name, 'wp_widget_rss', $widget_ops, array( 'number' => $o ));
     1177                wp_register_widget_control($id, $name, 'wp_widget_rss_control', $control_ops, array( 'number' => $o ));
     1178        }
    10871179}
    10881180
     
    11131205?>
    11141206        <p><label for="tag-cloud-title">
    1115         <?php _e('Title:') ?> <input type="text" style="width:300px" id="tag-cloud-title" name="tag-cloud-title" value="<?php echo $title ?>" /></label>
     1207        <?php _e('Title:') ?> <input type="text" class="widefat" id="tag-cloud-title" name="tag-cloud-title" value="<?php echo $title ?>" /></label>
    11161208        </p>
    11171209        <input type="hidden" name="tag-cloud-submit" id="tag-cloud-submit" value="1" />
     
    11231215                return;
    11241216
    1125         $GLOBALS['wp_register_widget_defaults'] = true;
    1126 
    1127         $dims90 = array( 'height' => 90, 'width' => 300 );
    1128         $dims100 = array( 'height' => 100, 'width' => 300 );
    1129         $dims150 = array( 'height' => 150, 'width' => 300 );
    1130 
    1131         $class = array('classname' => 'widget_pages');
    1132         wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $class);
    1133         wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control', $dims150);
    1134 
    1135         $class['classname'] = 'widget_calendar';
    1136         wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $class);
    1137         wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control', $dims90);
    1138 
    1139         $class['classname'] = 'widget_archives';
    1140         wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $class);
    1141         wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control', $dims100);
    1142 
    1143         $class['classname'] = 'widget_links';
    1144         wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $class);
    1145 
    1146         $class['classname'] = 'widget_meta';
    1147         wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $class);
    1148         wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control', $dims90);
    1149 
    1150         $class['classname'] = 'widget_search';
    1151         wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $class);
    1152 
    1153         $class['classname'] = 'widget_recent_entries';
    1154         wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $class);
    1155         wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control', $dims90);
    1156 
    1157         $class['classname'] = 'widget_tag_cloud';
    1158         wp_register_sidebar_widget('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud', $class);
    1159         wp_register_widget_control('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud_control', 'width=300&height=160');
     1217        $widget_ops = array('classname' => 'widget_pages', 'description' => __( "Your blog's WordPress Pages") );
     1218        wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $widget_ops);
     1219        wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control' );
     1220
     1221        $widget_ops = array('classname' => 'widget_calendar', 'description' => __( "A calendar of your blog's posts") );
     1222        wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $widget_ops);
     1223        wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control' );
     1224
     1225        $widget_ops = array('classname' => 'widget_archive', 'description' => __( "A monthly archive of your blog's posts") );
     1226        wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $widget_ops);
     1227        wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control' );
     1228
     1229        $widget_ops = array('classname' => 'widget_links', 'description' => __( "Your blogroll") );
     1230        wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $widget_ops);
     1231
     1232        $widget_ops = array('classname' => 'widget_meta', 'description' => __( "Log in/out, admin, feed and WordPress links") );
     1233        wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $widget_ops);
     1234        wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control' );
     1235
     1236        $widget_ops = array('classname' => 'widget_search', 'description' => __( "A search form for your blog") );
     1237        wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $widget_ops);
     1238
     1239        $widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "The most recent posts on your blog") );
     1240        wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $widget_ops);
     1241        wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control' );
     1242
     1243        $widget_ops = array('classname' => 'widget_tag_cloud', 'description' => __( "Your most used tags in cloud format") );
     1244        wp_register_sidebar_widget('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud', $widget_ops);
     1245        wp_register_widget_control('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud_control' );
    11601246
    11611247        wp_widget_categories_register();
     
    11641250        wp_widget_recent_comments_register();
    11651251
    1166         $GLOBALS['wp_register_widget_defaults'] = false;
    1167 
    11681252        do_action('widgets_init');
    11691253}
     
    11711255add_action('init', 'wp_widgets_init', 1);
    11721256
    1173 ?>
     1257/* Pattern for widget which allows multiple instances (such as the text widget)
     1258
     1259// Displays widget on blag
     1260// $widget_args: number
     1261//    number: which of the several widgets of this type do we mean
     1262function widget_many( $args, $widget_args = 1 ) {
     1263        extract( $args, EXTR_SKIP );
     1264        if ( is_numeric($widget_args) )
     1265                $widget_args = array( 'number' => $widget_args );
     1266        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     1267        extract( $widget_args, EXTR_SKIP );
     1268       
     1269        // Data should be stored as array:  array( number => data for that instance of the widget, ... )
     1270        $options = get_option('widget_many');
     1271        if ( !isset($options[$number]) )
     1272                return;
     1273
     1274        echo $before_widget;
     1275
     1276        // Do stuff for this widget, drawing data from $options[$number]
     1277
     1278        echo $after_widget;
     1279}
     1280
     1281// Displays form for a particular instance of the widget.  Also updates the data after a POST submit
     1282// $widget_args: number
     1283//    number: which of the several widgets of this type do we mean
     1284function widget_many_control( $widget_args = 1 ) {
     1285        global $wp_registered_widgets;
     1286        static $updated = false; // Whether or not we have already updated the data after a POST submit
     1287
     1288        if ( is_numeric($widget_args) )
     1289                $widget_args = array( 'number' => $widget_args );
     1290        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
     1291        extract( $widget_args, EXTR_SKIP );
     1292
     1293        // Data should be stored as array:  array( number => data for that instance of the widget, ... )
     1294        $options = get_option('widget_many');
     1295        if ( !is_array($options) )
     1296                $options = array();
     1297
     1298        // We need to update the data
     1299        if ( !$updated && !empty($_POST['sidebar']) ) {
     1300                // Tells us what sidebar to put the data in
     1301                $sidebar = (string) $_POST['sidebar'];
     1302
     1303                $sidebars_widgets = wp_get_sidebars_widgets();
     1304                if ( isset($sidebars_widgets[$sidebar]) )
     1305                        $this_sidebar =& $sidebars_widgets[$sidebar];
     1306                else
     1307                        $this_sidebar = array();
     1308
     1309                foreach ( $this_sidebar as $_widget_id ) {
     1310                        // Remove all widgets of this type from the sidebar.  We'll add the new data in a second.  This makes sure we don't get any duplicate data
     1311                        // since widget ids aren't necessarily persistent across multiple updates
     1312                        if ( 'widget_many' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) {
     1313                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
     1314                                unset($options[$widget_number]);
     1315                        }
     1316                }
     1317
     1318                foreach ( (array) $_POST['widget-many'] as $widget_number => $widget_many_instance ) {
     1319                        // compile data from $widget_many_instance
     1320                        $something = wp_specialchars( $widget_many_instance['something'] );
     1321                        $options[$widget_number] = array( 'something' => $something );  // Even simple widgets should store stuff in array, rather than in scalar
     1322                }
     1323
     1324                update_option('widget_text', $options);
     1325
     1326                $updated = true; // So that we don't go through this more than once
     1327        }
     1328
     1329
     1330        // Here we echo out the form
     1331        if ( -1 == $number ) { // We echo out a template for a form which can be converted to a specific form later via JS
     1332                $something = '';
     1333                $number = '%i%';
     1334        } else {
     1335                $something = attribute_escape($options[$number]['something']);
     1336        }
     1337
     1338        // The form has inputs with names like widget-many[$number][something] so that all data for that instance of
     1339        // the widget are stored in one $_POST variable: $_POST['widget-many'][$number]
     1340?>
     1341                <p>
     1342                        <input class="widefat" id="widget-many-something-<?php echo $number; ?>" name="widget-many[<?php echo $number; ?>][something]" type="text" value="<?php echo $data; ?>" />
     1343                        <input type="hidden" id="widget-many-submit-<?php echo $number; ?>" name="widget-many-<?php echo $number; ?>" value="1" />
     1344                </p>
     1345<?php
     1346}
     1347
     1348// Registers each instance of our widget on startup
     1349function widget_many_register() {
     1350        $options = get_option('widget_many');
     1351        $widget_ops = array('classname' => 'widget_many', 'description' => __('Widget which allows multiple instances'));
     1352        $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'many');
     1353        $name = __('Many');
     1354
     1355        // If there are none, we register the widget's existance with a generic template
     1356        if ( !$options ) {
     1357                wp_register_sidebar_widget( 'many-1', $name, 'widget_many', $widget_ops, array( 'number' => -1 ) );
     1358                wp_register_widget_control( 'many-1', $name, 'widget_many_control', $control_ops, array( 'number' => -1 ) );
     1359        }
     1360
     1361        foreach ( array_keys($options) as $o ) {
     1362                // Old widgets can have null values for some reason
     1363                if ( !isset($options[$o]['something']) ) // we used 'something' above in our exampple.  Replace with with whatever your real data are.
     1364                        continue;
     1365
     1366                // $id should look like {$id_base}-{$o}
     1367                $id = "many-$o"; // Never never never translate an id
     1368                wp_register_sidebar_widget( $id, $name, 'wp_widget_text', $widget_ops, array( 'number' => $o ) );
     1369                wp_register_widget_control( $id, $name, 'wp_widget_text_control', $control_ops, array( 'number' => $o ) );
     1370        }
     1371}
     1372
     1373// This is important
     1374add_action( 'widgets_init', 'widget_many_register' )
     1375
     1376*/
     1377
     1378?>
Note: See TracChangeset for help on using the changeset viewer.