WordPress.org

Make WordPress Core


Ignore:
Timestamp:
01/04/2008 11:34:33 PM (12 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.