WordPress.org

Make WordPress Core

Ticket #5583: 5583.diff

File 5583.diff, 82.8 KB (added by mdawaffe, 14 years ago)

big

  • wp-includes/widgets.php

     
    22
    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 */
    1412
     
    9593}
    9694
    9795function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) {
     96        global $wp_registered_widgets;
    9897
    99         global $wp_registered_widgets, $wp_register_widget_defaults;
    100 
    10198        if ( empty($output_callback) ) {
    10299                unset($wp_registered_widgets[$id]);
    103100                return;
     
    113110        );
    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;
    118115}
    119116
     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'] );
     125}
     126
    120127function unregister_sidebar_widget($id) {
    121128        return wp_unregister_sidebar_widget($id);
    122129}
     
    149156        call_user_func_array('wp_register_widget_control', $args);
    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) ) {
    156169                unset($wp_registered_widget_controls[$id]);
    157170                return;
    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(
    171182                'name' => $name,
     
    234245        return $did_one;
    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;
    239252
    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;
    248261}
     
    387400        $title = attribute_escape($options['title']);
    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}
    402421
     
    463482        $dropdown = $options['dropdown'] ? 'checked="checked"' : '';
    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
    471493}
     
    499521        }
    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
    505527}
     
    527549        }
    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'] );
    540571?>
     
    545576<?php
    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);
     618                $updated = true;
    561619        }
    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 }
    570620
    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;
     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']);
    578628        }
    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');
    588629?>
    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>
     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}
    601637
    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);
     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 ) );
    614648        }
    615         add_action('sidebar_admin_setup', 'wp_widget_text_setup');
    616         add_action('sidebar_admin_page', 'wp_widget_text_page');
     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        }
    617658}
    618659
    619 function wp_widget_categories($args, $number = 1) {
    620         extract($args);
     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';
    624673        $h = $options[$number]['hierarchical'] ? '1' : '0';
     
    635684                wp_dropdown_categories($cat_args . '&show_option_none= ' . __('Select Category'));
    636685?>
    637686
    638 <script type='text/javascript'><!--
     687<script type='text/javascript'>
     688/* <![CDATA[ */
    639689    var dropdown = document.getElementById("cat");
    640690    function onCatChange() {
    641691                if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
     
    643693                }
    644694    }
    645695    dropdown.onchange = onCatChange;
    646 --></script>
     696/* ]]> */
     697</script>
    647698
    648699<?php
    649700        } else {
     
    657708        echo $after_widget;
    658709}
    659710
    660 function wp_widget_categories_control( $number ) {
    661         $options = $newoptions = get_option('widget_categories');
     711function wp_widget_categories_control( $widget_args ) {
     712        global $wp_registered_widgets;
     713        static $updated = false;
    662714
    663         if ( !is_array( $options ) ) {
    664                 $options = $newoptions = get_option( 'widget_categories' );
    665         }
     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);
    666719
    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         }
     720        $options = get_option('widget_categories');
    673721
    674         if ( $options != $newoptions ) {
    675                 $options = $newoptions;
     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);
     750                $updated = true;
    677751        }
    678752
    679         $title = attribute_escape( $options[$number]['title'] );
     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        }
    680765?>
    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>
     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>
    684772
    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>
     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>
    688789
    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>
    696 
    697790                        <input type="hidden" id="categories-submit-<?php echo $number; ?>" name="categories-submit-<?php echo $number; ?>" value="1" />
    698791<?php
    699792}
    700793
    701 function wp_widget_categories_setup() {
    702         $options = $newoptions = get_option( 'widget_categories' );
     794function wp_widget_categories_register() {
     795        $options = get_option( 'widget_categories' );
     796        if ( isset($options['title']) )
     797                $options = wp_widget_categories_upgrade();
    703798
    704         if ( isset( $_POST['categories-number-submit'] ) ) {
    705                 $number = (int) $_POST['categories-number'];
     799        $widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "A list or dropdown of categories" ) );
    706800
    707                 if ( $number > 9 ) {
    708                         $number = 9;
    709                 } elseif ( $number < 1 ) {
    710                         $number = 1;
    711                 }
     801        $name = __( 'Categories' );
    712802
    713                 $newoptions['number'] = $number;
     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 ) );
    714807        }
    715808
    716         if ( $newoptions != $options ) {
    717                 $options = $newoptions;
    718                 update_option( 'widget_categories', $options );
    719                 wp_widget_categories_register( $options['number'] );
     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 ) );
    720816        }
    721 }
    722817
    723 function wp_widget_categories_page() {
    724         $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
    744818}
    745819
    746820function wp_widget_categories_upgrade() {
    747821        $options = get_option( 'widget_categories' );
    748822
    749         $newoptions = array( 'number' => 1, 1 => $options );
     823        if ( !isset( $options['title'] ) )
     824                return $options;
    750825
     826        $newoptions = array( 1 => $options );
     827
    751828        update_option( 'widget_categories', $newoptions );
    752829
    753830        $sidebars_widgets = get_option( 'sidebars_widgets' );
     
    764841                        update_option( 'sidebars_widgets', $new_widgets );
    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;
    779845}
    780846
    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' );
    809 }
    810 
    811847function wp_widget_recent_entries($args) {
    812848        if ( $output = wp_cache_get('widget_recent_entries') )
    813849                return print($output);
     
    861897        if ( !$number = (int) $options['number'] )
    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
    868909}
     
    916957        if ( !$number = (int) $options['number'] )
    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
    923968}
     
    929974}
    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') )
    938982                add_action('wp_head', 'wp_widget_recent_comments_style');
    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'];
    9491003        if ( empty($num_items) || $num_items < 1 || $num_items > 10 ) $num_items = 10;
     
    9521006                $url = substr($url, 1);
    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']));
    9571014        while ( strstr($link, 'http') != $link )
     
    10021059        echo $after_widget;
    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);
     1116                $updated = true;
    10261117        }
    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 }
    10401118
    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;
     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'];
    10481132        }
    1049         if ( $options != $newoptions ) {
    1050                 $options = $newoptions;
    1051                 update_option('widget_rss', $options);
    1052                 wp_widget_rss_register($options['number']);
    1053         }
    1054 }
    10551133
    1056 function wp_widget_rss_page() {
    1057         $options = get_option('widget_rss');
    10581134?>
    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>
     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}
    10711158
    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);
     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 ) );
    10841169        }
    1085         add_action('sidebar_admin_setup', 'wp_widget_rss_setup');
    1086         add_action('sidebar_admin_page', 'wp_widget_rss_page');
     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
    10891181function wp_widget_tag_cloud($args) {
     
    11121204        $title = attribute_escape( $options['title'] );
    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" />
    11181210<?php
     
    11221214        if ( !is_blog_installed() )
    11231215                return;
    11241216
    1125         $GLOBALS['wp_register_widget_defaults'] = true;
     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' );
    11261220
    1127         $dims90 = array( 'height' => 90, 'width' => 300 );
    1128         $dims100 = array( 'height' => 100, 'width' => 300 );
    1129         $dims150 = array( 'height' => 150, 'width' => 300 );
     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' );
    11301224
    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);
     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' );
    11341228
    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);
     1229        $widget_ops = array('classname' => 'widget_links', 'description' => __( "Your blogroll") );
     1230        wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $widget_ops);
    11381231
    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);
     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' );
    11421235
    1143         $class['classname'] = 'widget_links';
    1144         wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $class);
     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);
    11451238
    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);
     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' );
    11491242
    1150         $class['classname'] = 'widget_search';
    1151         wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $class);
     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' );
    11521246
    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');
    1160 
    11611247        wp_widget_categories_register();
    11621248        wp_widget_text_register();
    11631249        wp_widget_rss_register();
    11641250        wp_widget_recent_comments_register();
    11651251
    1166         $GLOBALS['wp_register_widget_defaults'] = false;
    1167 
    11681252        do_action('widgets_init');
    11691253}
    11701254
    11711255add_action('init', 'wp_widgets_init', 1);
    11721256
     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]
    11731340?>
     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?>
  • wp-includes/script-loader.php

     
    7979
    8080                $this->add( 'jquery', '/wp-includes/js/jquery/jquery.js', false, '1.1.4');
    8181                $this->add( 'jquery-form', '/wp-includes/js/jquery/jquery.form.js', array('jquery'), '1.0.3');
    82                 $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2');
     82                $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2' );
    8383                $this->add( 'dimensions', '/wp-includes/js/jquery/jquery.dimensions.min.js', array('jquery'), '1.1.2');
    8484                $this->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('dimensions'), '1.1');
    8585                $this->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20');
     
    143143                                'saveText' => attribute_escape(__('Save &raquo;')),
    144144                                'confirmText' => __("Are you sure you want to delete the file '%title%'?\nClick ok to delete or cancel to go back.")
    145145                        ) );
     146                        $this->add( 'admin-widgets', '/wp-admin/js/widgets.js', array( 'interface' ), mt_rand() );
    146147                }
    147148        }
    148149
  • wp-admin/admin-ajax.php

     
    11<?php
     2define('DOING_AJAX', true);
     3
    24require_once('../wp-config.php');
    35require_once('includes/admin.php');
    46
    5 define('DOING_AJAX', true);
    6 
    77if ( !is_user_logged_in() )
    88        die('-1');
    99
  • wp-admin/includes/widgets.php

     
     1<?php
     2
     3// $_search is unsanitized
     4function wp_list_widgets( $show = 'all', $_search = false ) {
     5        global $wp_registered_widgets, $sidebars_widgets;
     6        if ( $_search ) {
     7                // sanitize
     8                $search = preg_replace( '/[^\w\s]/', '', $_search );
     9                // array of terms
     10                $search_terms = preg_split( '/[\s]/', $search, -1, PREG_SPLIT_NO_EMPTY );
     11        } else {
     12                $search_terms = array();
     13        }
     14
     15        if ( !in_array( $show, array( 'all', 'unused', 'used' ) ) )
     16                $show = 'all';
     17?>
     18
     19        <ul id='widget-list'>
     20                <?php
     21                $no_widgets_shown = true;
     22                $already_shown = array();
     23                foreach ( $wp_registered_widgets as $name => $widget ) :
     24                        if ( in_array( $widget['callback'], $already_shown ) )
     25                                continue;
     26                        $already_shown[] = $widget['callback'];
     27
     28                        if ( $search_terms ) {
     29                                $hit = false;
     30                                // Simple case-insensitive search.  Boolean OR.
     31                                $search_text = preg_replace( '/[^\w]/', '', $widget['name'] );
     32                                if ( isset($widget['description']) )
     33                                        $search_text .= preg_replace( '/[^\w]/', '', $widget['description'] );
     34
     35                                foreach ( $search_terms as $search_term ) {
     36                                        if ( stristr( $search_text, $search_term ) ) {
     37                                                $hit = true;
     38                                                break;
     39                                        }
     40                                }
     41                                if ( !$hit )
     42                                        continue;
     43                        }
     44
     45                        $sidebar = is_active_widget( $widget['callback'] );
     46                        if ( ( 'unused' == $show && $sidebar ) || ( 'used' == $show && !$sidebar ) )
     47                                continue;
     48
     49                        ob_start();
     50                                wp_widget_control( 'no-key', $widget['id'], 'template' );
     51                        $widget_control_template = ob_get_contents();
     52                        ob_end_clean();
     53
     54                        if ( !$sidebar || false !== strpos( $widget_control_template, '%i%' ) ) {
     55                                $action = 'add';
     56                                $add_url = wp_nonce_url( add_query_arg( array(
     57                                        'sidebar' => $sidebar,
     58                                        'add' => $widget['id'],
     59                                        'key' => false,
     60                                        'edit' => false
     61                                ) ), "add-widget_$widget[id]" );
     62                        } else {
     63                                $action = 'edit';
     64                                $edit_url = add_query_arg( array(
     65                                        'sidebar' => $sidebar,
     66                                        'edit' => $widget['id'],
     67                                        'key' => array_search( $widget['id'], $sidebars_widgets[$sidebar] ),
     68                                ) );
     69                                $widget_control_template = "<textarea>$widget_control_template</textarea>";
     70                        }
     71
     72                        $no_widgets_shown = false;
     73
     74                ?>
     75
     76                <li id="widget-list-item-<?php echo attribute_escape( $widget['id'] ); ?>" class="widget-list-item">
     77                        <h4 class="widget-title widget-draggable">
     78
     79                                <?php echo wp_specialchars( $widget['name'] ); ?>
     80
     81                                <?php if ( 'add' == $action ) : ?>
     82
     83                                <a class="widget-action widget-control-add" href="<?php echo $add_url; ?>"><?php _e( 'Add' ); ?></a>
     84
     85                                <?php elseif ( 'edit' == $action ) :
     86                                        // We echo a hidden edit link for the sake of the JS.  Edit links are shown (needlessly?) after a widget is added.
     87                                ?>
     88
     89                                <a class="widget-action widget-control-edit" href="<?php echo $edit_url; ?>" style="display: none;"><?php _e( 'Edit' ); ?></a>
     90
     91                                <?php endif; ?>
     92
     93                        </h4>
     94
     95
     96                        <ul id="widget-control-info-<?php echo $widget['id']; ?>" class="widget-control-info">
     97
     98                                <?php echo $widget_control_template; ?>
     99
     100                        </ul>
     101
     102                        <?php if ( 'add' == $action ) : ?>
     103                        <?php endif; ?>
     104
     105                        <div class="widget-description">
     106                                <?php echo wp_widget_description( $widget['id'] ); ?>
     107                        </div>
     108
     109                        <br class="clear" />
     110
     111                </li>
     112
     113                <?php endforeach; if ( $no_widgets_shown ) : ?>
     114               
     115                <li><?php _e( 'No matching widgets' ); ?></li>
     116
     117                <?php endif; ?>
     118
     119        </ul>
     120<?php
     121}
     122
     123function wp_list_widget_controls( $widgets, $edit_widget = -1 ) {
     124?>
     125
     126                <ul class="widget-control-list">
     127
     128<?php
     129        foreach ( $widgets as $key => $widget )
     130                wp_widget_control( $key, $widget, $key == $edit_widget ? 'edit' : 'display' );
     131?>
     132
     133                </ul>
     134
     135<?php
     136}
     137
     138
     139/*
     140 * Displays the control form for widget of type $widget at position $key.
     141 * $display
     142 *  == 'display': Normal, "closed" form.
     143 *  == 'edit': "open" form
     144 *  == 'template': generates a form template to be used by JS
     145 */
     146function wp_widget_control( $key, $widget, $display = 'display' ) {
     147        static $i = 0;
     148        global $wp_registered_widgets, $wp_registered_widget_controls;
     149        $control = $wp_registered_widget_controls[$widget];
     150        $widget  = $wp_registered_widgets[$widget];
     151
     152        $id_format = $widget['id'];
     153        if ( 'template' == $display && isset($control['params'][0]['number']) ) {
     154                // number == -1 implies a template where id numbers are replaced by a generic '%i%'
     155                $control['params'][0]['number'] = -1;
     156                // if given, id_base means widget id's should be constructed like {$id_base}-{$id_number}
     157                if ( isset($control['id_base']) )
     158                        $id_format = $control['id_base'] . '-%i%';
     159        }
     160?>
     161
     162                <li id="widget-list-control-item-<?php echo ++$i; ?>-<?php echo $widget['id']; ?>" class="widget-list-control-item widget-sortable">
     163                        <h4 class="widget-title">
     164
     165                                <?php echo $widget['name']; // TODO: Up/Down links for noJS reordering? ?>
     166
     167                                <?php if ( 'edit' == $display ) : ?>
     168
     169                                <a class="widget-action widget-control-edit" href="<?php echo remove_query_arg( array( 'edit', 'key' ) ); ?>"><?php _e('Cancel'); ?></a>
     170
     171                                <?php else : ?>
     172
     173                                <a class="widget-action widget-control-edit" href="<?php echo add_query_arg( array( 'edit' => $id_format, 'key' => $key ) ); ?>"><?php _e('Edit'); ?></a>
     174
     175                                <?php endif; ?>
     176
     177                        </h4>
     178
     179                        <div class="widget-control"<?php if ( 'edit' == $display ) echo ' style="display: block;"'; ?>>
     180
     181                                <?php
     182                                if ( $control )
     183                                        call_user_func_array( $control['callback'], $control['params'] );
     184                                else
     185                                        echo '<p>' . __('There are no options for this widget.') . '</p>';
     186                                ?>
     187
     188                                <input type="hidden" name="widget-id[]" value="<?php echo $id_format; ?>" />
     189                                <input type="hidden" class="widget-width" value="<?php echo $control['width']; ?>" />
     190
     191                                <div class="widget-control-actions">
     192
     193                                        <?php if ( $control && 'edit' != $display ) : ?>
     194
     195                                        <a class="widget-action widget-control-save edit alignleft" href="#save:<?php echo $id_format; ?>"><?php _e('Save'); ?></a>
     196
     197                                        <?php endif; ?>
     198
     199                                        <a class="widget-action widget-control-remove delete alignright" href="<?php echo add_query_arg( array( 'remove' => $id_format, 'key' => $key ), wp_nonce_url( null, "remove-widget_$widget[id]" ) ); ?>"><?php _e('Remove'); ?></a>
     200                                        <br class="clear" />
     201                                </div>
     202                        </div>
     203                </li>
     204
     205<?php
     206}
     207
     208function temp_widget_css() {
     209?>
     210
     211<style type="text/css">
     212/* 2 column liquid layout */
     213div.widget-liquid-left-holder {
     214        float: left;
     215        clear: left;
     216        width: 100%;
     217        margin-right: -310px;
     218}
     219
     220div.widget-liquid-left {
     221        margin-right: 310px;
     222}
     223
     224div.widget-liquid-right {
     225        float: right;
     226        clear: right;
     227        width: 300px;
     228}
     229
     230p.submit {
     231        clear: both;
     232}
     233
     234/* pasitioning etc. */
     235form#widgets-filter {
     236        position: relative;
     237}
     238
     239p#widget-search {
     240        position: absolute;
     241        right: 0;
     242        top: 0;
     243        margin: 0;
     244}
     245
     246ul#widget-list {
     247        list-style: none;
     248        margin: 0;
     249        padding: 0;
     250}
     251
     252ul#widget-list li.widget-list-item {
     253        padding: .7em 1em;
     254        margin: 0;
     255        border-top:    1px solid #ccc;
     256        border-bottom: 1px solid #ccc;
     257        background-color: transparent;
     258        line-height: 1;
     259}
     260
     261ul#widget-list li.widget-list-item h4.widget-title {
     262        position: relative;
     263        margin: 0;
     264        padding: .5em 1em;
     265        width: 200px;
     266        float: left;
     267        background-color: #ccc;
     268        color: #000;
     269}
     270
     271#dragHelper h4.widget-title {
     272        color: #fff;
     273        background-color: #2683ae;
     274        padding: .5em 1em;
     275        margin: 0;
     276}
     277
     278ul#widget-list li.widget-list-item div.widget-description {
     279        display: block;
     280        margin: 0 0 0 200px;
     281        padding: 0 0 0 4em;
     282}
     283
     284
     285ul#widget-list li.widget-list-item ul.widget-control-info {
     286        display: none;
     287}
     288
     289div#sidebar-info {
     290        padding: 0 1em;
     291        margin-bottom: 1em;
     292}
     293
     294ul.widget-control-list {
     295        list-style: none;
     296        margin: 0;
     297        padding: 0 1em;
     298}
     299
     300li.widget-list-control-item {
     301        background-color: #eaf3fa;
     302        margin: 0 0 1em;
     303}
     304
     305li.widget-list-control-item h4, #dragHelper li.widget-list-control-item h4 {
     306        position: relative;
     307        margin: 0;
     308        background-color: #2683ae;
     309        padding: .5em 1em;
     310        color: #fff;
     311}
     312
     313div.widget-control a.widget-action, div.widget-control a.widget-action:hover {
     314        padding: .5em 1em;
     315}
     316
     317h4.widget-title a {
     318        position: absolute;
     319        right: 1em;
     320        text-decoration: underline;
     321        border-bottom: none;
     322}
     323
     324li.widget-list-control-item h4.widget-title a, li.widget-list-control-item h4.widget-title a:visited {
     325        color: #fff;
     326}
     327
     328li.widget-list-control-item h4.widget-title a:hover {
     329        color: #fff;
     330        text-decoration: none;
     331        border-bottom: none;
     332}
     333
     334li.widget-list-control-item div.widget-control {
     335        display: none;
     336        margin: 1em;
     337        padding: 0 10px 0 0; /* Correction for padding, margin, border of inputs */
     338}
     339
     340li.widget-list-control-item div.widget-control p {
     341        margin: 0 0 1em;
     342        padding: 0;
     343}
     344
     345ul.widget-control-list div.widget-control-actions {
     346        margin-right: -10px; /* Correction for padding, margin, border of inputs */
     347        padding: 0 0 1em;
     348}
     349
     350ul.widget-control-list .sorthelper {
     351        background-color: #ccf3fa;
     352
     353}
     354
     355#current-widgets .drop-widget-here {
     356        background-color: #ffc
     357}
     358
     359ul.widget-control-list select option {
     360}
     361</style>
     362
     363<?php
     364}
     365
     366add_action( 'admin_head', 'temp_widget_css' );
     367
     368?>
  • wp-admin/includes/admin.php

     
    1313require_once(ABSPATH . 'wp-admin/includes/theme.php');
    1414require_once(ABSPATH . 'wp-admin/includes/user.php');
    1515require_once(ABSPATH . 'wp-admin/includes/update.php');
     16require_once(ABSPATH . 'wp-admin/includes/widgets.php');
    1617
    1718require_once(ABSPATH . WPINC . '/registration.php');
    1819
  • wp-admin/js/widgets.js

     
     1jQuery(function($) {
     2        $('.noscript-action').remove();
     3
     4        // TODO: i18n
     5        var addText  = 'Add';
     6        var editText = 'Edit';
     7        var cancText = 'Cancel';
     8        var increment = 1;
     9
     10        // Open or close widget control form
     11        var toggleWidget = function( li ) {
     12                var width = li.find('input.widget-width').val();
     13                return li.children('div.widget-control').each( function() {
     14                        var t = $(this);
     15                        if ( t.is(':visible') ) {
     16                                t.animate( { height: 'hide' } );
     17                                if ( width > 250 )
     18                                        li.animate( { marginLeft: 0 } );
     19                                t.siblings('h4').children('a').text( editText );
     20                        } else {
     21                                t.animate( { height: 'show' } );
     22                                if ( width > 250 )
     23                                        li.animate( { marginLeft: ( width - 250 ) * -1 } );
     24                                t.siblings('h4').children('a').text( cancText );
     25                        }
     26                } ).end();
     27        };
     28
     29        // onclick for edit links
     30        var editClick = function() {
     31                var q = wpAjax.unserialize( this.href );
     32                // if link is in available widgets list, make sure it points to the current sidebar
     33                if ( ( q.sidebar && q.sidebar == $('#sidebar').val() ) || q.add ) {
     34                        var w = q.edit || q.add;
     35                        toggleWidget( $('#current-sidebar .widget-control-list input[@name^="widget-id"][@value=' + w + ']').parents('li:first') ).blur();
     36                        return false;
     37                } else if ( q.sidebar ) { // otherwise, redirect to correct page
     38                        return true;
     39                }
     40
     41                // If link is in current widgets list, just open the form
     42                toggleWidget( $(this).parents('li:first') ).blur();
     43                return false;
     44        };
     45
     46        // onclick for add links
     47        var addClick = function() {
     48                var oldLi = $(this).parents('li:first').find('ul.widget-control-info li');
     49                var newLi = oldLi.clone();
     50
     51                if ( newLi.html().match( /%i%/ ) ) {
     52                        // supplid form is a template, replace %i% by unique id
     53                        var i = $('#generated-time').val() + increment.toString();
     54                        increment++;
     55                        newLi.html( newLi.html().replace( /%i%/g, i ) );
     56                } else {
     57                        $(this).text( editText ).unbind().click( editClick );
     58                        // save form content in textarea so we don't have any conflicting HTML ids
     59                        oldLi.html( '<textarea>' + oldLi.html() + '</textarea>' );
     60                }
     61
     62                // add event handlers
     63                addWidgetControls( newLi );
     64
     65                // add widget to sidebar sortable
     66                widgetSortable.append( newLi ).SortableAddItem( newLi[0] );
     67
     68                // increment widget counter
     69                var n = parseInt( $('#widget-count').text(), 10 ) + 1;
     70                $('#widget-count').text( n.toString() )
     71
     72                return false;
     73        };
     74
     75        // add event handlers to all links found in context
     76        var addWidgetControls = function( context ) {
     77                if ( !context )
     78                        context = document;
     79               
     80                $('a.widget-control-edit', context).click( editClick );
     81
     82                // onclick for save links
     83                $('a.widget-control-save', context).click( function() {
     84                        toggleWidget( $(this).parents('li:first') ).blur()
     85                        return false;
     86                } );
     87
     88                // onclick for remove links
     89                $('a.widget-control-remove', context).click( function() {
     90                        var w = $(this).parents('li:first').find('input[@name^="widget-id"]').val();
     91                        $(this).parents('li:first').remove();
     92                        var t = $('#widget-list ul#widget-control-info-' + w + ' textarea');
     93                        t.parent().html( t.text() ).parents('li.widget-list-item:first').children( 'h4' ).children('a.widget-action')
     94                                .show().text( addText ).unbind().click( addClick );
     95                        var n = parseInt( $('#widget-count').text(), 10 ) - 1;
     96                        $('#widget-count').text( n.toString() )
     97                        return false;
     98                } );
     99        }
     100
     101        addWidgetControls();
     102
     103        $('a.widget-control-add').click( addClick );
     104
     105        // initialize sortable
     106        var widgetSortable = $('#current-sidebar .widget-control-list').Sortable( {
     107                accept: 'widget-sortable',
     108                helperclass: 'sorthelper',
     109                handle: 'h4.widget-title'
     110        } );
     111
     112});
  • wp-admin/widgets.php

     
    11<?php
    22
    3 require_once 'admin.php';
     3require_once( 'admin.php' );
    44
    55if ( ! current_user_can('switch_themes') )
    66        wp_die( __( 'Cheatin&#8217; uh?' ));
    77
    8 wp_enqueue_script('interface');
     8wp_enqueue_script( array( 'wp-lists', 'admin-widgets' ) );
    99
    10 function wp_widgets_admin_head() {
    11         global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls;
    12 ?>
    13         <?php wp_admin_css( 'css/widgets' ); ?>
    14         <!--[if IE 7]>
    15         <style type="text/css">
    16                 #palette { float: <?php echo ( get_bloginfo( 'text_direction' ) == 'rtl' ) ? 'right' : 'left'; ?>; }
    17         </style>
    18         <![endif]-->
    19 <?php
     10do_action( 'sidebar_admin_setup' );
    2011
    21         $cols = array();
    22         foreach ( $wp_registered_sidebars as $index => $sidebar ) {
    23                 $cols[] = '\'' . $index . '\'';
    24         }
    25         $cols = implode( ', ', $cols );
     12$title = __( 'Widgets' );
     13$parent_file = 'themes.php';
    2614
    27         $widgets = array();
    28         foreach ( $wp_registered_widgets as $name => $widget ) {
    29                 $widgets[] = '\'' . $widget['id'] . '\'';
    30         }
    31         $widgets = implode( ', ', $widgets );
     15// $sidebar = What sidebar are we editing?
     16if ( isset($_GET['sidebar']) && isset($wp_registered_sidebars[$_GET['sidebar']]) ) {
     17        $sidebar = attribute_escape( $_GET['sidebar'] );
     18} elseif ( is_array($wp_registered_sidebars) && !empty($wp_registered_sidebars) ) {
     19        // By default we look at the first defined sidebar
     20        $sidebar = array_shift( array_keys($wp_registered_sidebars) );
     21} else {
     22        // If no sidebars, die.
     23        require_once( 'admin-header.php' );
    3224?>
    33 <script type="text/javascript">
    34 // <![CDATA[
    35         var cols = [<?php echo $cols; ?>];
    36         var widgets = [<?php echo $widgets; ?>];
    37         var controldims = new Array;
    38         <?php foreach ( $wp_registered_widget_controls as $name => $widget ) : ?>
    39                 controldims['#<?php echo $widget['id']; ?>control'] = new Array;
    40                 controldims['#<?php echo $widget['id']; ?>control']['width'] = <?php echo (int) $widget['width']; ?>;
    41                 controldims['#<?php echo $widget['id']; ?>control']['height'] = <?php echo (int) $widget['height']; ?>;
    42         <?php endforeach; ?>
    43         function initWidgets() {
    44         <?php foreach ( $wp_registered_widget_controls as $name => $widget ) : ?>
    45                 jQuery('#<?php echo $widget['id']; ?>popper').click(function() {popControl('#<?php echo $widget['id']; ?>control');});
    46                 jQuery('#<?php echo $widget['id']; ?>closer').click(function() {unpopControl('#<?php echo $widget['id']; ?>control');});
    47                 jQuery('#<?php echo $widget['id']; ?>control').Draggable({handle: '.controlhandle', zIndex: 1000});
    48                 if ( true && window.opera )
    49                         jQuery('#<?php echo $widget['id']; ?>control').css('border','1px solid #bbb');
    50         <?php endforeach; ?>
    51                 jQuery('#shadow').css('opacity','0');
    52                 jQuery(widgets).each(function(o) {o='#widgetprefix-'+o; jQuery(o).css('position','relative');} );
    53         }
    54         function resetDroppableHeights() {
    55                 var max = 6;
    56                 jQuery.map(cols, function(o) {
    57                         var c = jQuery('#' + o + ' li').length;
    58                         if ( c > max ) max = c;
    59                 });
    60                 var maxheight = 35 * ( max + 1);
    61                 jQuery.map(cols, function(o) {
    62                         height = 0 == jQuery('#' + o + ' li').length ? maxheight - jQuery('#' + o + 'placemat').height() : maxheight;
    63                         jQuery('#' + o).height(height);
    64                 });
    65         }
    66         function maxHeight(elm) {
    67                 htmlheight = document.body.parentNode.clientHeight;
    68                 bodyheight = document.body.clientHeight;
    69                 var height = htmlheight > bodyheight ? htmlheight : bodyheight;
    70                 jQuery(elm).height(height);
    71         }
    72         function getViewportDims() {
    73                 var x,y;
    74                 if (self.innerHeight) { // all except Explorer
    75                         x = self.innerWidth;
    76                         y = self.innerHeight;
    77                 } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
    78                         x = document.documentElement.clientWidth;
    79                         y = document.documentElement.clientHeight;
    80                 } else if (document.body) { // other Explorers
    81                         x = document.body.clientWidth;
    82                         y = document.body.clientHeight;
    83                 }
    84                 return new Array(x,y);
    85         }
    86         function dragChange(o) {
    87                 var p = getViewportDims();
    88                 var screenWidth = p[0];
    89                 var screenHeight = p[1];
    90                 var elWidth = parseInt( jQuery(o).css('width') );
    91                 var elHeight = parseInt( jQuery(o).css('height') );
    92                 var elLeft = parseInt( jQuery(o).css('left') );
    93                 var elTop = parseInt( jQuery(o).css('top') );
    94                 if ( screenWidth < ( parseInt(elLeft) + parseInt(elWidth) ) )
    95                         jQuery(o).css('left', ( screenWidth - elWidth ) + 'px' );
    96                 if ( screenHeight < ( parseInt(elTop) + parseInt(elHeight) ) )
    97                         jQuery(o).css('top', ( screenHeight - elHeight ) + 'px' );
    98                 if ( elLeft < 1 )
    99                         jQuery(o).css('left', '1px');
    100                 if ( elTop < 1 )
    101                         jQuery(o).css('top', '1px');
    102         }
    103         function popControl(elm) {
    104                 var x = ( document.body.clientWidth - controldims[elm]['width'] ) / 2;
    105                 var y = ( document.body.parentNode.clientHeight - controldims[elm]['height'] ) / 2;
    106                 jQuery(elm).css({display: 'block', width: controldims[elm]['width'] + 'px', height: controldims[elm]['height'] + 'px', position: 'absolute', right: x + 'px', top: y + 'px', zIndex: '1000' });
    107                 jQuery(elm).attr('class','control');
    108                 jQuery('#shadow').click(function() {unpopControl(elm);});
    109                 window.onresize = function(){maxHeight('#shadow');dragChange(elm);};
    110                 popShadow();
    111         }
    112         function popShadow() {
    113                 maxHeight('#shadow');
    114                 jQuery('#shadow').css({zIndex: '999', display: 'block'});
    115                 jQuery('#shadow').fadeTo('fast', 0.2);
    116         }
    117         function unpopShadow() {
    118                 jQuery('#shadow').fadeOut('fast', function() {jQuery('#shadow').hide()});
    119         }
    120         function unpopControl(el) {
    121                 jQuery(el).attr('class','hidden');
    122                 jQuery(el).hide();
    123                 unpopShadow();
    124         }
    125         function serializeAll() {
    126         <?php $i = 0; foreach ( $wp_registered_sidebars as $index => $sidebar ) : $i++; ?>
    127                 var serial<?php echo $i ?> = jQuery.SortSerialize('<?php echo $index ?>');
    128                 jQuery('#<?php echo $index ?>order').attr('value',serial<?php echo $i ?>.hash.replace(/widgetprefix-/g, ''));
    129         <?php endforeach; ?>
    130         }
    131         function updateAll() {
    132                 jQuery.map(cols, function(o) {
    133                         if ( jQuery('#' + o + ' li').length )
    134                                 jQuery('#'+o+'placemat span.handle').hide();
    135                         else
    136                                 jQuery('#'+o+'placemat span.handle').show();
    137                 });
    138                 resetDroppableHeights();
    139         }
    140         jQuery(document).ready( function() {
    141                 updateAll();
    142                 initWidgets();
    143         });
    144 // ]]>
    145 </script>
     25
     26        <div class="error">
     27                <p><?php _e( 'No Sidebars Defined' ); ?></p>
     28        </div>
     29
     30        <div class="wrap">
     31                <p><?php _e( 'You are seeing this message because the theme you are currently using isn&#8217;t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please <a href="http://automattic.com/code/widgets/themes/">follow these instructions</a>.' ); /* TODO: article on codex */; ?></p>
     32        </div>
     33
    14634<?php
     35        require_once( 'admin-footer.php' );
     36        exit;
    14737}
    148 add_action( 'admin_head', 'wp_widgets_admin_head' );
    149 do_action( 'sidebar_admin_setup' );
    15038
    151 function wp_widget_draggable( $name ) {
    152         global $wp_registered_widgets, $wp_registered_widget_controls;
     39// These are the widgets grouped by sidebar
     40$sidebars_widgets = wp_get_sidebars_widgets();
     41if ( empty( $sidebars_widgets ) )
     42        $sidebars_widgets = wp_get_widget_defaults();
    15343
    154         if ( !isset( $wp_registered_widgets[$name] ) ) {
    155                 return;
    156         }
     44// for the sake of PHP warnings
     45if ( empty( $sidebars_widgets[$sidebar] ) )
     46        $sidebars_widgets[$sidebar] = array();
    15747
    158         $sanitized_name = sanitize_title( $wp_registered_widgets[$name]['id'] );
    159         $link_title = __( 'Configure' );
    160         $popper = ( isset( $wp_registered_widget_controls[$name] ) )
    161                 ? ' <div class="popper" id="' . $sanitized_name . 'popper" title="' . $link_title . '">&#8801;</div>'
    162                 : '';
     48$http_post = ( 'POST' == $_SERVER['REQUEST_METHOD'] );
    16349
    164         $output = '<li class="module" id="widgetprefix-%1$s"><span class="handle">%2$s</span></li>';
     50// We're updating a sidebar
     51if ( $http_post && isset($sidebars_widgets[$_POST['sidebar']]) ) {
    16552
    166         printf( $output, $sanitized_name, $wp_registered_widgets[$name]['name'] . $popper );
    167 }
     53        /* Hack #1
     54         * The widget_control is overloaded.  It updates the widget's options AND echoes out the widget's HTML form.
     55         * Since we want to update before sending out any headers, we have to catchi it with an output buffer
     56         */
     57        ob_start();
     58                /* There can be multiple widgets of the same type, but the widget_control for that
     59                 * widget type needs only be called once.
     60                 */
     61                $already_done = array();
    16862
    169 $title = __( 'Widgets' );
    170 $parent_file = 'themes.php';
     63                foreach ( $wp_registered_widget_controls as $name => $control ) {
     64                        if ( in_array( $control['callback'], $already_done ) )
     65                                continue;
    17166
    172 require_once 'admin-header.php';
     67                        if ( is_callable( $control['callback'] ) )
     68                                call_user_func_array( $control['callback'], $control['params'] );
     69                }
     70        ob_end_clean();
    17371
    174 if ( count( $wp_registered_sidebars ) < 1 ) {
    175 ?>
    176         <div class="wrap">
    177                 <h2><?php _e( 'No Sidebars Defined' ); ?></h2>
     72        // Prophylactic.  Take out empty ids.
     73        foreach ( (array) $_POST['widget-id'] as $key => $val )
     74                if ( !$val )
     75                        unset($_POST['widget-id'][$key]);
    17876
    179                 <p><?php _e( 'You are seeing this message because the theme you are currently using isn&#8217;t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please <a href="http://automattic.com/code/widgets/themes/">follow these instructions</a>.' ); /* TODO: article on codex */; ?></p>
    180         </div>
    181 <?php
     77        // Reset the key numbering and stare
     78        $new_sidebar = array_values( $_POST['widget-id'] );
     79        $sidebars_widgets[$_POST['sidebar']] = $new_sidebar;
     80        wp_set_sidebars_widgets( $sidebars_widgets );
    18281
    183         require_once 'admin-footer.php';
     82        // Re-register just in case
     83        wp_widgets_init();
     84
     85        wp_redirect( add_query_arg( 'message', 'updated' ) );
    18486        exit;
    18587}
    18688
    187 $sidebars_widgets = wp_get_sidebars_widgets();
    18889
    189 if ( empty( $sidebars_widgets ) ) {
    190         $sidebars_widgets = wp_get_widget_defaults();
     90
     91
     92// What widget (if any) are we editing
     93$edit_widget = -1;
     94
     95$query_args = array('add', 'remove', 'key', 'edit', '_wpnonce', 'message' );
     96
     97if ( isset($_GET['add']) && $_GET['add'] ) {
     98        // Add to the end of the sidebar
     99        if ( isset($wp_registered_widgets[$_GET['add']]) ) {
     100                check_admin_referer( "add-widget_$_GET[add]" );
     101                $sidebars_widgets[$sidebar][] = $_GET['add'];
     102                wp_set_sidebars_widgets( $sidebars_widgets );
     103        }
     104        wp_redirect( remove_query_arg( $query_args ) );
     105        exit;
     106} elseif ( isset($_GET['remove']) && $_GET['remove'] && isset($_GET['key']) && is_numeric($_GET['key']) ) {
     107        // Remove from sidebar the widget of type $_GET['remove'] and in position $_GET['key']
     108        $key = (int) $_GET['key'];
     109        if ( -1 < $key && ( $keys = array_keys($sidebars_widgets[$sidebar], $_GET['remove']) ) && in_array($key, $keys) ) {
     110                check_admin_referer( "remove-widget_$_GET[remove]" );
     111                unset($sidebars_widgets[$sidebar][$key]);
     112                $sidebars_widgets[$sidebar] = array_values($sidebars_widgets[$sidebar]);
     113                wp_set_sidebars_widgets( $sidebars_widgets );
     114        }
     115        wp_redirect( remove_query_arg( $query_args ) );
     116        exit;
     117} elseif ( isset($_GET['edit']) && $_GET['edit'] && isset($_GET['key']) && is_numeric($_GET['key']) ) {
     118        // Edit widget of type $_GET['edit'] and position $_GET['key']
     119        $key = (int) $_GET['key'];
     120        if ( -1 < $key && ( $keys = array_keys($sidebars_widgets[$sidebar], $_GET['edit']) ) && in_array($key, $keys) )
     121                $edit_widget = $key;
    191122}
    192123
    193 if ( isset( $_POST['action'] ) ) {
    194         check_admin_referer( 'widgets-save-widget-order' );
     124// Total number of registered sidebars
     125$sidebar_widget_count = count($sidebars_widgets[$sidebar]);
    195126
    196         switch ( $_POST['action'] ) {
    197                 case 'default' :
    198                         $sidebars_widgets = wp_get_widget_defaults();
    199                         wp_set_sidebars_widgets( $sidebars_widgets );
    200                 break;
     127// This is sort of lame since "widget" won't be converted to "widgets" in the JS
     128if ( 1 < $sidebars_count = count($wp_registered_sidebars) )
     129        $sidebar_info_text = __ngettext( 'You are using %1$s widget in the "%2$s" sidebar.', 'You are using %1$s widgets in the "%2$s" sidebar.', $sidebar_widget_count );
     130else
     131        $sidebar_info_text = __ngettext( 'You are using %1$s widget in the sidebar.', 'You are using %1$s widgets in the sidebar.', $sidebar_widget_count );
    201132
    202                 case 'save_widget_order' :
    203                         $sidebars_widgets = array();
    204133
    205                         foreach ( $wp_registered_sidebars as $index => $sidebar ) {
    206                                 $postindex = $index . 'order';
     134$sidebar_info_text = sprintf( wp_specialchars( $sidebar_info_text ), "<span id='widget-count'>$sidebar_widget_count</span>", $wp_registered_sidebars[$sidebar]['name'] );
    207135
    208                                 parse_str( $_POST[$postindex], $order );
     136$page = isset($_GET['apage']) ? abs( (int) $_GET['apage'] ) : 1;
    209137
    210                                 $new_order = $order[$index];
     138/* TODO: Paginate widgets list
     139$page_links = paginate_links( array(
     140        'base'    => add_query_arg( 'apage', '%#%' ),
     141        'format'  => '',
     142        'total'   => ceil(($total = 105 )/ 10),
     143        'current' => $page
     144));
     145*/
     146$page_links = false;
    211147
    212                                 if ( is_array( $new_order ) ) {
    213                                         foreach ( $new_order as $sanitized_name ) {
    214                                                 foreach ( $wp_registered_widgets as $name => $widget ) {
    215                                                         if ( $sanitized_name == $widget['id'] ) {
    216                                                                 $sidebars_widgets[$index][] = $name;
    217                                                         }
    218                                                 }
    219                                         }
    220                                 }
    221                         }
     148// Unsanitized!
     149$widget_search = isset($_GET['s']) ? $_GET['s'] : false;
    222150
    223                         wp_set_sidebars_widgets( $sidebars_widgets );
    224                 break;
    225         }
    226 }
     151// Not entirely sure what all should be here
     152$show_values = array(
     153        ''       => $widget_search ? __( 'Show any widgets' ) : __( 'Show all widgets' ),
     154        'unused' => __( 'Show unused widgets' ),
     155        'used'   => __( 'Show used widgets' )
     156);
    227157
    228 ksort( $wp_registered_widgets );
     158$show = isset($_GET['show']) && isset($show_values[$_GET['show']]) ? attribute_escape( $_GET['show'] ) : false;
    229159
    230 $inactive_widgets = array();
    231160
    232 foreach ( $wp_registered_widgets as $name => $widget ) {
    233         $is_active = false;
     161$messages = array(
     162        'updated' => __('Changes saved.')
     163);
    234164
    235         foreach ( $wp_registered_sidebars as $index => $sidebar ) {
    236                 if ( is_array( $sidebars_widgets[$index] ) && in_array( $name, $sidebars_widgets[$index] ) ) {
    237                         $is_active = true;
    238                         break;
    239                 }
    240         }
     165require_once( 'admin-header.php' );
    241166
    242         if ( !$is_active ) {
    243                 $inactive_widgets[] = $name;
    244         }
    245 }
     167if ( isset($_GET['message']) && isset($messages[$_GET['message']]) ) : ?>
    246168
    247 $containers = array( 'palette' );
     169<div id="message" class="updated fade"><p><?php echo $messages[$_GET['message']]; ?></p></div>
    248170
    249 foreach ( $wp_registered_sidebars as $index => $sidebar ) {
    250         $containers[] = $index;
    251 }
     171<?php endif; ?>
    252172
    253 $c_string = '';
     173<div class="wrap">
    254174
    255 foreach ( $containers as $container ) {
    256         $c_string .= '"' . $container . '",';
    257 }
     175        <form id="widgets-filter" action="" method="get">
    258176
    259 $c_string = substr( $c_string, 0, -1 );
     177        <h2><?php _e( 'Widgets' ); ?></h2>
     178        <p id="widget-search">
     179                <input type="text" id="widget-search-input" name="s" value="<?php echo attribute_escape( $widget_search ); ?>" />
     180                <input type="submit" value="<?php _e( 'Search Widgets' ); ?>" />
     181        </p>
    260182
    261 if ( isset( $_POST['action'] ) ) {
    262 ?>
    263         <div class="fade updated" id="message">
    264                 <p><?php printf( __( 'Sidebar updated. <a href="%s">View site &raquo;</a>' ), get_bloginfo( 'url' ) . '/' ); ?></p>
     183        <div class="widget-liquid-left-holder">
     184        <div id="available-widgets-filter" class="widget-liquid-left">
     185                <h3><?php printf( __('Available Widgets %s'), '<a href="#help:avaliable-widgets" class="wp-context-help">?</a>' ); ?></h3>
     186                <p>
     187                        <select name="show">
     188<?php foreach ( $show_values as $show_value => $show_text ) : $show_value = attribute_escape( $show_value ); ?>
     189                                <option value='<?php echo $show_value; ?>'<?php selected( $show_value, $show ); ?>><?php echo wp_specialchars( $show_text ); ?></option>
     190<?php endforeach; ?>
     191                        </select>
     192                        <input type="submit" value="<?php _e('Show' ); ?>" />
     193                </p>
     194<?php if ( $page_links ) : ?>
     195                <p class="pagenav">
     196                        <?php echo $page_links; ?>
     197
     198                </p>
     199<?php endif; ?>
    265200        </div>
    266 <?php
    267 }
    268 ?>
    269         <div class="wrap">
    270                 <h2><?php _e( 'Sidebar Arrangement' ); ?></h2>
     201        </div>
    271202
    272                 <p><?php _e( 'You can drag and drop widgets onto your sidebar below.' ); ?></p>
     203        <div id="available-sidebars" class="widget-liquid-right">
     204                <h3><?php printf( __('Current Widgets %s'), '<a href="#help:current-widgets" class="wp-context-help">?</a>' ); ?></h3>
    273205
    274                 <form id="sbadmin" method="post" onsubmit="serializeAll();">
    275                         <p class="submit">
    276                                 <input type="submit" value="<?php _e( 'Save Changes &raquo;' ); ?>" />
    277                         </p>
    278                         <div id="zones">
    279                         <?php
    280                                 foreach ( $wp_registered_sidebars as $index => $sidebar ) {
    281                         ?>
    282                                 <input type="hidden" id="<?php echo $index; ?>order" name="<?php echo $index; ?>order" value="" />
     206<?php if ( 1 < $sidebars_count ) : ?>
    283207
    284                                 <div class="dropzone">
    285                                         <h3><?php echo $sidebar['name']; ?></h3>
     208                <p>
     209                        <select id="sidebar-selector" name="sidebar">
     210<?php foreach ( $wp_registered_sidebars as $sidebar_id => $registered_sidebar ) : $sidebar_id = attribute_escape( $sidebar_id ); ?>
     211                                <option value='<?php echo $sidebar_id; ?>'<?php selected( $sidebar_id, $sidebar ); ?>><?php echo wp_specialchars( $registered_sidebar['name'] ); ?></option>
     212<?php endforeach; ?>
     213                        </select>
     214                        <input type="submit" value="<?php _e('Go' ); ?>" />
     215                </p>
    286216
    287                                         <div id="<?php echo $index; ?>placemat" class="placemat">
    288                                                 <span class="handle">
    289                                                         <h4><?php _e( 'Default Sidebar' ); ?></h4>
    290                                                         <?php _e( 'Your theme will display its usual sidebar when this box is empty. Dragging widgets into this box will replace the usual sidebar with your customized sidebar.' ); ?>
    291                                                 </span>
    292                                         </div>
     217<?php endif; ?>
    293218
    294                                         <ul id="<?php echo $index; ?>">
    295                                         <?php
    296                                                 if ( is_array( $sidebars_widgets[$index] ) ) {
    297                                                         foreach ( $sidebars_widgets[$index] as $name ) {
    298                                                                 wp_widget_draggable( $name );
    299                                                         }
    300                                                 }
    301                                         ?>
    302                                         </ul>
    303                                 </div>
    304                         <?php
    305                                 }
    306                         ?>
     219        </div>
    307220
    308                         </div>
     221        </form>
    309222
    310                         <div id="palettediv">
    311                                 <h3><?php _e( 'Available Widgets' ); ?></h3>
     223        <div id="widget-content" class="widget-liquid-left-holder">
    312224
    313                                 <ul id="palette">
    314                                 <?php
    315                                         foreach ( $inactive_widgets as $name ) {
    316                                                 wp_widget_draggable( $name );
    317                                         }
    318                                 ?>
    319                                 </ul>
    320                         </div>
     225                <div id="available-widgets" class="widget-liquid-left">
    321226
    322                         <script type="text/javascript">
    323                         // <![CDATA[
    324                                 jQuery(document).ready(function(){
    325                         <?php foreach ( $containers as $container ) { ?>
    326                                         jQuery('ul#<?php echo $container; ?>').Sortable({
    327                                                 accept: 'module', activeclass: 'activeDraggable', opacity: 0.8, revert: true, onStop: updateAll
    328                                         });
    329                         <?php } ?>
    330                                 });
    331                         // ]]>
    332                         </script>
     227                        <?php wp_list_widgets( $show, $widget_search ); // This lists all the widgets for the query ( $show, $search ) ?>
    333228
    334                         <p class="submit">
    335                         <?php wp_nonce_field( 'widgets-save-widget-order' ); ?>
    336                                 <input type="hidden" name="action" id="action" value="save_widget_order" />
    337                                 <input type="submit" value="<?php _e( 'Save Changes &raquo;' ); ?>" />
     229<?php if ( $page_links ) : ?>
     230                        <p class="pagenav">
     231                                <?php echo $page_links; ?>
     232
    338233                        </p>
     234<?php endif; ?>
    339235
    340                         <div id="controls">
    341                         <?php foreach ( $wp_registered_widget_controls as $name => $widget ) { ?>
    342                                 <div class="hidden" id="<?php echo $widget['id']; ?>control">
    343                                         <span class="controlhandle"><?php echo $widget['name']; ?></span>
    344                                         <span id="<?php echo $widget['id']; ?>closer" class="controlcloser">&#215;</span>
    345                                         <div class="controlform">
    346                                         <?php call_user_func_array( $widget['callback'], $widget['params'] ); ?>
    347                                         </div>
    348                                 </div>
    349                         <?php } ?>
    350                         </div>
    351                 </form>
     236                </div>
     237        </div>
    352238
    353                 <br class="clear" />
     239        <form id="widget-controls" action="" method="post">
     240
     241        <div id="current-widgets-head" class="widget-liquid-right">
     242
     243                <div id="sidebar-info">
     244                        <p><?php echo $sidebar_info_text; ?></p>
     245                        <p><?php _e( 'Add more from the Available Widgets section.' ); ?></p>
     246                </div>
     247
    354248        </div>
    355249
    356         <div id="shadow"> </div>
     250        <div id="current-widgets" class="widget-liquid-right">
     251                <input type="hidden" id='sidebar' name='sidebar' value="<?php echo $sidebar; ?>" />
    357252
    358         <?php do_action( 'sidebar_admin_page' ); ?>
     253                <div id="current-sidebar">
    359254
    360 <?php require_once 'admin-footer.php'; ?>
     255                        <?php wp_list_widget_controls( $sidebars_widgets[$sidebar], $edit_widget ); // Show the control forms for each of the widgets in this sidebar ?>
     256
     257                </div>
     258        </div>
     259
     260        <p class="submit">
     261                <input type="hidden" id="generated-time" name="generated-time" value="<?php echo time(); ?>" />
     262                <input type="submit" name="save-widgets" value="<?php _e( 'Save Changes' ); ?>" />
     263        </p>
     264
     265        </form>
     266
     267</div>
     268
     269<?php do_action( 'sidebar_admin_page' ); ?>
     270
     271<?php require_once( 'admin-footer.php' ); ?>
     272