WordPress.org

Make WordPress Core

Ticket #11817: menus.diff

File menus.diff, 93.0 KB (added by scribu, 4 years ago)

pre-alpha

  • wp-includes/menu-template.php

     
     1<?php 
     2 
     3// TODO 
     4 
  • wp-includes/default-menu-items.php

     
     1<?php 
     2 
     3/** 
     4 * Home Menu Item class 
     5 * 
     6 * @since 3.0 
     7 */ 
     8class WP_Menu_Item_Home extends WP_Menu_Item { 
     9 
     10        function WP_Menu_Item_Home() { 
     11                $menu_item_ops = array('classname' => 'menu_item_home', 'description' => __('The site homepage') ); 
     12                $this->WP_Menu_Item('home', __('Home'), $menu_item_ops); 
     13        } 
     14         
     15        function output( $args, $instance ) { 
     16                // TODO 
     17        } 
     18} 
     19 
     20/** 
     21 * Page Menu Item class 
     22 * 
     23 * @since 3.0 
     24 */ 
     25class WP_Menu_Item_Page extends WP_Menu_Item { 
     26 
     27        function WP_Menu_Item_Page() { 
     28                $menu_item_ops = array('classname' => 'menu_item_page', 'description' => __('A WordPress page') ); 
     29                $this->WP_Menu_Item('page', __('Page'), $menu_item_ops); 
     30        } 
     31 
     32        function output( $args, $instance ) { 
     33                extract( $args ); 
     34 
     35                $title = apply_filters('menu_title', empty( $instance['title'] ) ? __( 'Page' ) : $instance['title']); 
     36                $sortby = empty( $instance['sortby'] ) ? 'menu_order' : $instance['sortby']; 
     37                $exclude = empty( $instance['exclude'] ) ? '' : $instance['exclude']; 
     38 
     39                if ( $sortby == 'menu_order' ) 
     40                        $sortby = 'menu_order, post_title'; 
     41 
     42                wp_list_page( apply_filters('menu_page_args', array('title_li' => '', 'sort_column' => $sortby, 'exclude' => $exclude) ) ); 
     43        } 
     44 
     45        function update( $new_instance, $old_instance ) { 
     46                $instance = $old_instance; 
     47                $instance['title'] = strip_tags($new_instance['title']); 
     48                if ( in_array( $new_instance['sortby'], array( 'post_title', 'menu_order', 'ID' ) ) ) { 
     49                        $instance['sortby'] = $new_instance['sortby']; 
     50                } else { 
     51                        $instance['sortby'] = 'menu_order'; 
     52                } 
     53 
     54                $instance['exclude'] = strip_tags( $new_instance['exclude'] ); 
     55 
     56                return $instance; 
     57        } 
     58 
     59        function form( $instance ) { 
     60                //Defaults 
     61                $instance = wp_parse_args( (array) $instance, array( 'sortby' => 'post_title', 'title' => '', 'exclude' => '') ); 
     62                $title = esc_attr( $instance['title'] ); 
     63                $exclude = esc_attr( $instance['exclude'] ); 
     64        ?> 
     65                <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p> 
     66                <p> 
     67                        <label for="<?php echo $this->get_field_id('sortby'); ?>"><?php _e( 'Sort by:' ); ?></label> 
     68                        <select name="<?php echo $this->get_field_name('sortby'); ?>" id="<?php echo $this->get_field_id('sortby'); ?>" class="widefat"> 
     69                                <option value="post_title"<?php selected( $instance['sortby'], 'post_title' ); ?>><?php _e('Page title'); ?></option> 
     70                                <option value="menu_order"<?php selected( $instance['sortby'], 'menu_order' ); ?>><?php _e('Page order'); ?></option> 
     71                                <option value="ID"<?php selected( $instance['sortby'], 'ID' ); ?>><?php _e( 'Page ID' ); ?></option> 
     72                        </select> 
     73                </p> 
     74                <p> 
     75                        <label for="<?php echo $this->get_field_id('exclude'); ?>"><?php _e( 'Exclude:' ); ?></label> <input type="text" value="<?php echo $exclude; ?>" name="<?php echo $this->get_field_name('exclude'); ?>" id="<?php echo $this->get_field_id('exclude'); ?>" class="widefat" /> 
     76                        <br /> 
     77                        <small><?php _e( 'Page IDs, separated by commas.' ); ?></small> 
     78                </p> 
     79<?php 
     80        } 
     81} 
     82 
     83 
     84/** 
     85 * Link menu item class 
     86 * 
     87 * @since 3.0 
     88 */ 
     89class WP_Menu_Item_Link extends WP_Menu_Item { 
     90 
     91        function WP_Menu_Item_Link() { 
     92                $menu_item_ops = array('description' => __('An external link') ); 
     93                $this->WP_Menu_Item('link', __('Link'), $menu_item_ops); 
     94        } 
     95 
     96        function output( $args, $instance ) { 
     97                extract($args, EXTR_SKIP); 
     98 
     99                $show_description = isset($instance['description']) ? $instance['description'] : false; 
     100                $show_name = isset($instance['name']) ? $instance['name'] : false; 
     101                $show_rating = isset($instance['rating']) ? $instance['rating'] : false; 
     102                $show_images = isset($instance['images']) ? $instance['images'] : true; 
     103                $category = isset($instance['category']) ? $instance['category'] : false; 
     104 
     105                wp_list_bookmarks(apply_filters('menu_item_links_args', array( 
     106                        'title_before' => $before_title, 'title_after' => $after_title, 
     107                        'show_images' => $show_images, 'show_description' => $show_description, 
     108                        'show_name' => $show_name, 'show_rating' => $show_rating, 
     109                        'category' => $category, 'class' => 'linkcat menu_item' 
     110                ))); 
     111        } 
     112 
     113        function update( $new_instance, $old_instance ) { 
     114                $new_instance = (array) $new_instance; 
     115                $instance = array( 'images' => 0, 'name' => 0, 'description' => 0, 'rating' => 0); 
     116                foreach ( $instance as $field => $val ) { 
     117                        if ( isset($new_instance[$field]) ) 
     118                                $instance[$field] = 1; 
     119                } 
     120                $instance['category'] = intval($new_instance['category']); 
     121 
     122                return $instance; 
     123        } 
     124 
     125        function form( $instance ) { 
     126 
     127                //Defaults 
     128                $instance = wp_parse_args( (array) $instance, array( 'images' => true, 'name' => true, 'description' => false, 'rating' => false, 'category' => false ) ); 
     129                $link_cats = get_terms( 'link_category'); 
     130?> 
     131                <p> 
     132                <label for="<?php echo $this->get_field_id('category'); ?>" class="screen-reader-text"><?php _e('Select Link Category'); ?></label> 
     133                <select class="widefat" id="<?php echo $this->get_field_id('category'); ?>" name="<?php echo $this->get_field_name('category'); ?>"> 
     134                <option value=""><?php _e('All Links'); ?></option> 
     135                <?php 
     136                foreach ( $link_cats as $link_cat ) { 
     137                        echo '<option value="' . intval($link_cat->term_id) . '"' 
     138                                . ( $link_cat->term_id == $instance['category'] ? ' selected="selected"' : '' ) 
     139                                . '>' . $link_cat->name . "</option>\n"; 
     140                } 
     141                ?> 
     142                </select></p> 
     143                <p> 
     144                <input class="checkbox" type="checkbox" <?php checked($instance['images'], true) ?> id="<?php echo $this->get_field_id('images'); ?>" name="<?php echo $this->get_field_name('images'); ?>" /> 
     145                <label for="<?php echo $this->get_field_id('images'); ?>"><?php _e('Show Link Image'); ?></label><br /> 
     146                <input class="checkbox" type="checkbox" <?php checked($instance['name'], true) ?> id="<?php echo $this->get_field_id('name'); ?>" name="<?php echo $this->get_field_name('name'); ?>" /> 
     147                <label for="<?php echo $this->get_field_id('name'); ?>"><?php _e('Show Link Name'); ?></label><br /> 
     148                <input class="checkbox" type="checkbox" <?php checked($instance['description'], true) ?> id="<?php echo $this->get_field_id('description'); ?>" name="<?php echo $this->get_field_name('description'); ?>" /> 
     149                <label for="<?php echo $this->get_field_id('description'); ?>"><?php _e('Show Link Description'); ?></label><br /> 
     150                <input class="checkbox" type="checkbox" <?php checked($instance['rating'], true) ?> id="<?php echo $this->get_field_id('rating'); ?>" name="<?php echo $this->get_field_name('rating'); ?>" /> 
     151                <label for="<?php echo $this->get_field_id('rating'); ?>"><?php _e('Show Link Rating'); ?></label> 
     152                </p> 
     153<?php 
     154        } 
     155} 
     156 
     157/** 
     158 * Category menu item class 
     159 * 
     160 * @since 3.0 
     161 */ 
     162class WP_Menu_Item_Category extends WP_Menu_Item { 
     163 
     164        function WP_Menu_Item_Category() { 
     165                $menu_item_ops = array( 'classname' => 'menu_item_category', 'description' => __('A WordPress category') ); 
     166                $this->WP_Menu_Item('category', __('Category'), $menu_item_ops); 
     167        } 
     168 
     169        function output( $args, $instance ) { 
     170                extract( $args ); 
     171 
     172                $title = apply_filters('menu_item_title', empty( $instance['title'] ) ? __( 'Categories' ) : $instance['title']); 
     173                $c = $instance['count'] ? '1' : '0'; 
     174                $h = $instance['hierarchical'] ? '1' : '0'; 
     175                $d = $instance['dropdown'] ? '1' : '0'; 
     176 
     177                $cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h); 
     178 
     179                if ( $d ) { 
     180                        $cat_args['show_option_none'] = __('Select Category'); 
     181                        wp_dropdown_categories(apply_filters('menu_item_category_dropdown_args', $cat_args)); 
     182?> 
     183 
     184<script type='text/javascript'> 
     185/* <![CDATA[ */ 
     186        var dropdown = document.getElementById("cat"); 
     187        function onCatChange() { 
     188                if ( dropdown.options[dropdown.selectedIndex].value > 0 ) { 
     189                        location.href = "<?php echo home_url(); ?>/?cat="+dropdown.options[dropdown.selectedIndex].value; 
     190                } 
     191        } 
     192        dropdown.onchange = onCatChange; 
     193/* ]]> */ 
     194</script> 
     195 
     196<?php 
     197                } else { 
     198?> 
     199                <ul> 
     200<?php 
     201                $cat_args['title_li'] = ''; 
     202                wp_list_categories(apply_filters('menu_item_category_args', $cat_args)); 
     203?> 
     204                </ul> 
     205<?php 
     206                } 
     207        } 
     208 
     209        function update( $new_instance, $old_instance ) { 
     210                $instance = $old_instance; 
     211                $instance['title'] = strip_tags($new_instance['title']); 
     212                $instance['count'] = $new_instance['count'] ? 1 : 0; 
     213                $instance['hierarchical'] = $new_instance['hierarchical'] ? 1 : 0; 
     214                $instance['dropdown'] = $new_instance['dropdown'] ? 1 : 0; 
     215 
     216                return $instance; 
     217        } 
     218 
     219        function form( $instance ) { 
     220                //Defaults 
     221                $instance = wp_parse_args( (array) $instance, array( 'title' => '') ); 
     222                $title = esc_attr( $instance['title'] ); 
     223                $count = isset($instance['count']) ? (bool) $instance['count'] :false; 
     224                $hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false; 
     225                $dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false; 
     226?> 
     227                <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e( 'Title:' ); ?></label> 
     228                <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p> 
     229 
     230                <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('dropdown'); ?>" name="<?php echo $this->get_field_name('dropdown'); ?>"<?php checked( $dropdown ); ?> /> 
     231                <label for="<?php echo $this->get_field_id('dropdown'); ?>"><?php _e( 'Show as dropdown' ); ?></label><br /> 
     232 
     233                <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>"<?php checked( $count ); ?> /> 
     234                <label for="<?php echo $this->get_field_id('count'); ?>"><?php _e( 'Show post counts' ); ?></label><br /> 
     235 
     236                <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('hierarchical'); ?>" name="<?php echo $this->get_field_name('hierarchical'); ?>"<?php checked( $hierarchical ); ?> /> 
     237                <label for="<?php echo $this->get_field_id('hierarchical'); ?>"><?php _e( 'Show hierarchy' ); ?></label></p> 
     238<?php 
     239        } 
     240} 
     241 
     242/** 
     243 * Register all of the default WordPress menu items on startup. 
     244 * 
     245 * Calls 'menu_items_init' action after all of the WordPress menu items have been 
     246 * registered. 
     247 * 
     248 * @since 3.0 
     249 */ 
     250function wp_menu_items_init() { 
     251        if ( !is_blog_installed() ) 
     252                return; 
     253 
     254        register_menu_item('WP_Menu_Item_Home'); 
     255        register_menu_item('WP_Menu_Item_Page'); 
     256        register_menu_item('WP_Menu_Item_Link'); 
     257        register_menu_item('WP_Menu_Item_Category'); 
     258 
     259        do_action('menu_items_init'); 
     260} 
     261 
     262add_action('init', 'wp_menu_items_init', 1); 
     263 
  • wp-includes/menus.php

     
     1<?php 
     2/** 
     3 * API for creating dynamic menus without hardcoding functionality into 
     4 * themes. Includes both internal WordPress routines and theme use routines. 
     5 * 
     6 * @link http://codex.wordpress.org/Plugins/WordPress_Menu_Items WordPress Menu_Items 
     7 * @link http://codex.wordpress.org/Plugins/WordPress_Menu_Items_Api Menu_Items API 
     8 * 
     9 * @package WordPress 
     10 * @subpackage Menus 
     11 */ 
     12 
     13/** 
     14 * This class must be extended for each menu item and WP_Menu_Item::menu_item(), WP_Menu_Item::update() 
     15 * and WP_Menu_Item::form() need to be over-ridden. 
     16 * 
     17 * @package WordPress 
     18 * @subpackage Menu_Items 
     19 * @since 3.0 
     20 */ 
     21class WP_Menu_Item { 
     22 
     23        var $id_base;                   // Root id for all menu_items of this type. 
     24        var $name;                              // Name for this menu_item type. 
     25        var $menu_item_options; // Option array passed to wp_register_menu_item() 
     26        var $control_options;   // Option array passed to wp_register_menu_item_control() 
     27 
     28        var $number = false;    // Unique ID number of the current instance. 
     29        var $id = false;                // Unique ID string of the current instance (id_base-number) 
     30        var $updated = false;   // Set true when we update the data after a POST submit - makes sure we don't do it twice. 
     31 
     32        // Member functions that you must over-ride. 
     33 
     34        /** Echo the menu_item content. 
     35         * 
     36         * Subclasses should over-ride this function to generate their menu_item code. 
     37         * 
     38         * @param array $args Display arguments including before_title, after_title, before_menu_item, and after_menu_item. 
     39         * @param array $instance The settings for the particular instance of the menu_item 
     40         */ 
     41        function output($args, $instance) { 
     42                die('function WP_Menu_Item::menu_item() must be over-ridden in a sub-class.'); 
     43        } 
     44 
     45        /** Update a particular instance. 
     46         * 
     47         * This function should check that $new_instance is set correctly. 
     48         * The newly calculated value of $instance should be returned. 
     49         * If "false" is returned, the instance won't be saved/updated. 
     50         * 
     51         * @param array $new_instance New settings for this instance as input by the user via form() 
     52         * @param array $old_instance Old settings for this instance 
     53         * @return array Settings to save or bool false to cancel saving 
     54         */ 
     55        function update($new_instance, $old_instance) { 
     56                return $new_instance; 
     57        } 
     58 
     59        /** Echo the settings update form 
     60         * 
     61         * @param array $instance Current settings 
     62         */ 
     63        function form($instance) { 
     64                echo '<p class="no-options-menu_item">' . __('There are no options for this menu item.') . '</p>'; 
     65                return 'noform'; 
     66        } 
     67 
     68        // Functions you'll need to call. 
     69 
     70        /** 
     71         * PHP4 constructor 
     72         */ 
     73        function WP_Menu_Item( $id_base = false, $name, $menu_item_options = array(), $control_options = array() ) { 
     74                $this->__construct( $id_base, $name, $menu_item_options, $control_options ); 
     75        } 
     76 
     77        /** 
     78         * PHP5 constructor 
     79         * 
     80         * @param string $id_base Optional Base ID for the menu_item, lower case, 
     81         * if left empty a portion of the menu_item's class name will be used. Has to be unique. 
     82         * @param string $name Name for the menu_item displayed on the configuration page. 
     83         * @param array $menu_item_options Optional Passed to wp_register_menu_item() 
     84         *       - description: shown on the configuration page 
     85         *       - classname 
     86         * @param array $control_options Optional Passed to wp_register_menu_item_control() 
     87         *       - width: required if more than 250px 
     88         *       - height: currently not used but may be needed in the future 
     89         */ 
     90        function __construct( $id_base = false, $name, $menu_item_options = array(), $control_options = array() ) { 
     91                $this->id_base = empty($id_base) ? preg_replace( '/(wp_)?menu_item_/', '', strtolower(get_class($this)) ) : strtolower($id_base); 
     92                $this->name = $name; 
     93                $this->option_name = 'menu_item_' . $this->id_base; 
     94                $this->menu_item_options = wp_parse_args( $menu_item_options, array('classname' => $this->option_name) ); 
     95                $this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) ); 
     96        } 
     97 
     98        /** 
     99         * Constructs name attributes for use in form() fields 
     100         * 
     101         * This function should be used in form() methods to create name attributes for fields to be saved by update() 
     102         * 
     103         * @param string $field_name Field name 
     104         * @return string Name attribute for $field_name 
     105         */ 
     106        function get_field_name($field_name) { 
     107                return 'menu_item-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']'; 
     108        } 
     109 
     110        /** 
     111         * Constructs id attributes for use in form() fields 
     112         * 
     113         * This function should be used in form() methods to create id attributes for fields to be saved by update() 
     114         * 
     115         * @param string $field_name Field name 
     116         * @return string ID attribute for $field_name 
     117         */ 
     118        function get_field_id($field_name) { 
     119                return 'menu_item-' . $this->id_base . '-' . $this->number . '-' . $field_name; 
     120        } 
     121 
     122        // Private Functions. Don't worry about these. 
     123 
     124        function _register() { 
     125                $settings = $this->get_settings(); 
     126                $empty = true; 
     127 
     128                if ( is_array($settings) ) { 
     129                        foreach ( array_keys($settings) as $number ) { 
     130                                if ( is_numeric($number) ) { 
     131                                        $this->_set($number); 
     132                                        $this->_register_one($number); 
     133                                        $empty = false; 
     134                                } 
     135                        } 
     136                } 
     137 
     138                if ( $empty ) { 
     139                        // If there are none, we register the menu_item's existance with a 
     140                        // generic template 
     141                        $this->_set(1); 
     142                        $this->_register_one(); 
     143                } 
     144        } 
     145 
     146        function _set($number) { 
     147                $this->number = $number; 
     148                $this->id = $this->id_base . '-' . $number; 
     149        } 
     150 
     151        function _get_display_callback() { 
     152                return array(&$this, 'display_callback'); 
     153        } 
     154 
     155        function _get_update_callback() { 
     156                return array(&$this, 'update_callback'); 
     157        } 
     158 
     159        function _get_form_callback() { 
     160                return array(&$this, 'form_callback'); 
     161        } 
     162 
     163        /** Generate the actual menu_item content. 
     164         *      Just finds the instance and calls menu_item(). 
     165         *      Do NOT over-ride this function. */ 
     166        function display_callback( $args, $menu_item_args = 1 ) { 
     167                if ( is_numeric($menu_item_args) ) 
     168                        $menu_item_args = array( 'number' => $menu_item_args ); 
     169 
     170                $menu_item_args = wp_parse_args( $menu_item_args, array( 'number' => -1 ) ); 
     171                $this->_set( $menu_item_args['number'] ); 
     172                $instance = $this->get_settings(); 
     173 
     174                if ( array_key_exists( $this->number, $instance ) ) { 
     175                        $instance = $instance[$this->number]; 
     176                        // filters the menu_item's settings, return false to stop displaying the menu_item 
     177                        $instance = apply_filters('menu_item_display_callback', $instance, $this, $args); 
     178                        if ( false !== $instance ) 
     179                                $this->menu_item($args, $instance); 
     180                } 
     181        } 
     182 
     183        /** Deal with changed settings. 
     184         *      Do NOT over-ride this function. */ 
     185        function update_callback( $menu_item_args = 1 ) { 
     186                global $wp_registered_menu_items; 
     187 
     188                if ( is_numeric($menu_item_args) ) 
     189                        $menu_item_args = array( 'number' => $menu_item_args ); 
     190 
     191                $menu_item_args = wp_parse_args( $menu_item_args, array( 'number' => -1 ) ); 
     192                $all_instances = $this->get_settings(); 
     193 
     194                // We need to update the data 
     195                if ( $this->updated ) 
     196                        return; 
     197 
     198                $wp_menu_items = wp_get_menu_items(); 
     199 
     200                if ( isset($_POST['delete_menu_item']) && $_POST['delete_menu_item'] ) { 
     201                        // Delete the settings for this instance of the menu_item 
     202                        if ( isset($_POST['the-menu_item-id']) ) 
     203                                $del_id = $_POST['the-menu_item-id']; 
     204                        else 
     205                                return; 
     206 
     207                        if ( isset($wp_registered_menu_items[$del_id]['params'][0]['number']) ) { 
     208                                $number = $wp_registered_menu_items[$del_id]['params'][0]['number']; 
     209 
     210                                if ( $this->id_base . '-' . $number == $del_id ) 
     211                                        unset($all_instances[$number]); 
     212                        } 
     213                } else { 
     214                        if ( isset($_POST['menu_item-' . $this->id_base]) && is_array($_POST['menu_item-' . $this->id_base]) ) { 
     215                                $settings = $_POST['menu_item-' . $this->id_base]; 
     216                        } elseif ( isset($_POST['id_base']) && $_POST['id_base'] == $this->id_base ) { 
     217                                $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['menu_item_number']; 
     218                                $settings = array( $num => array() ); 
     219                        } else { 
     220                                return; 
     221                        } 
     222 
     223                        foreach ( $settings as $number => $new_instance ) { 
     224                                $new_instance = stripslashes_deep($new_instance); 
     225                                $this->_set($number); 
     226 
     227                                $old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array(); 
     228 
     229                                $instance = $this->update($new_instance, $old_instance); 
     230 
     231                                // filters the menu_item's settings before saving, return false to cancel saving (keep the old settings if updating) 
     232                                $instance = apply_filters('menu_item_update_callback', $instance, $new_instance, $old_instance, $this); 
     233                                if ( false !== $instance ) 
     234                                        $all_instances[$number] = $instance; 
     235 
     236                                break; // run only once 
     237                        } 
     238                } 
     239 
     240                $this->save_settings($all_instances); 
     241                $this->updated = true; 
     242        } 
     243 
     244        /** Generate the control form. 
     245         *      Do NOT over-ride this function. */ 
     246        function form_callback( $menu_item_args = 1 ) { 
     247                if ( is_numeric($menu_item_args) ) 
     248                        $menu_item_args = array( 'number' => $menu_item_args ); 
     249 
     250                $menu_item_args = wp_parse_args( $menu_item_args, array( 'number' => -1 ) ); 
     251                $all_instances = $this->get_settings(); 
     252 
     253                if ( -1 == $menu_item_args['number'] ) { 
     254                        // We echo out a form where 'number' can be set later 
     255                        $this->_set('__i__'); 
     256                        $instance = array(); 
     257                } else { 
     258                        $this->_set($menu_item_args['number']); 
     259                        $instance = $all_instances[ $menu_item_args['number'] ]; 
     260                } 
     261 
     262                // filters the menu_item admin form before displaying, return false to stop displaying it 
     263                $instance = apply_filters('menu_item_form_callback', $instance, $this); 
     264 
     265                $return = null; 
     266                if ( false !== $instance ) { 
     267                        $return = $this->form($instance); 
     268                        // add extra fields in the menu_item form - be sure to set $return to null if you add any 
     269                        // if the menu_item has no form the text echoed from the default form method can be hidden using css 
     270                        do_action_ref_array( 'in_menu_item_form', array(&$this, &$return, $instance) ); 
     271                } 
     272                return $return; 
     273        } 
     274 
     275        /** Helper function: Registers a single instance. */ 
     276        function _register_one($number = -1) { 
     277                wp_register_menu_item(  $this->id, $this->name, $this->_get_display_callback(), $this->menu_item_options, array( 'number' => $number ) ); 
     278                _register_menu_item_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) ); 
     279                _register_menu_item_form_callback(      $this->id, $this->name, $this->_get_form_callback(), $this->control_options, array( 'number' => $number ) ); 
     280        } 
     281 
     282        function save_settings($settings) { 
     283                update_option( $this->option_name, $settings ); 
     284        } 
     285 
     286        function get_settings() { 
     287                $settings = get_option($this->option_name); 
     288 
     289                if ( false === $settings && isset($this->alt_option_name) ) 
     290                        $settings = get_option($this->alt_option_name); 
     291 
     292                if ( !is_array($settings) ) 
     293                        $settings = array(); 
     294 
     295                unset($settings['__i__']); 
     296                return $settings; 
     297        } 
     298} 
     299 
     300/** 
     301 * Singleton that registers and instantiates WP_Menu_Item classes. 
     302 * 
     303 * @package WordPress 
     304 * @subpackage Menu_Items 
     305 * @since 3.0 
     306 */ 
     307class WP_Menu_Item_Factory { 
     308        var $menu_items = array(); 
     309 
     310        function WP_Menu_Item_Factory() { 
     311                add_action( 'menu_items_init', array( &$this, '_register_menu_items' ), 100 ); 
     312        } 
     313 
     314        function register($menu_item_class) { 
     315                $this->menu_items[$menu_item_class] = & new $menu_item_class(); 
     316        } 
     317 
     318        function unregister($menu_item_class) { 
     319                if ( isset($this->menu_items[$menu_item_class]) ) 
     320                        unset($this->menu_items[$menu_item_class]); 
     321        } 
     322 
     323        function _register_menu_items() { 
     324                global $wp_registered_menu_items; 
     325                $keys = array_keys($this->menu_items); 
     326                $registered = array_keys($wp_registered_menu_items); 
     327                $registered = array_map('_get_menu_item_id_base', $registered); 
     328 
     329                foreach ( $keys as $key ) { 
     330                        // don't register new menu_item if old menu_item with the same id is already registered 
     331                        if ( in_array($this->menu_items[$key]->id_base, $registered, true) ) { 
     332                                unset($this->menu_items[$key]); 
     333                                continue; 
     334                        } 
     335 
     336                        $this->menu_items[$key]->_register(); 
     337                } 
     338        } 
     339} 
     340 
     341/* Global Variables */ 
     342 
     343/** @ignore */ 
     344global $wp_registered_menus, $wp_registered_menu_items, $wp_registered_menu_item_controls, $wp_registered_menu_item_updates; 
     345 
     346/** 
     347 * Stores the menus, since many themes can have more than one. 
     348 * 
     349 * @global array $wp_registered_menus 
     350 * @since 3.0.0 
     351 */ 
     352$wp_registered_menus = array(); 
     353 
     354/** 
     355 * Stores the registered menu_items. 
     356 * 
     357 * @global array $wp_registered_menu_items 
     358 * @since 3.0.0 
     359 */ 
     360$wp_registered_menu_items = array(); 
     361 
     362/** 
     363 * Stores the registered menu_item control (options). 
     364 * 
     365 * @global array $wp_registered_menu_item_controls 
     366 * @since 3.0.0 
     367 */ 
     368$wp_registered_menu_item_controls = array(); 
     369$wp_registered_menu_item_updates = array(); 
     370 
     371/** 
     372 * Private 
     373 */ 
     374$_wp_menu_items = array(); 
     375 
     376/* Template tags & API functions */ 
     377 
     378/** 
     379 * Register a menu_item 
     380 * 
     381 * Registers a WP_Menu_Item menu_item 
     382 * 
     383 * @since 3.0.0 
     384 * 
     385 * @see WP_Menu_Item 
     386 * @see WP_Menu_Item_Factory 
     387 * @uses WP_Menu_Item_Factory 
     388 * 
     389 * @param string $menu_item_class The name of a class that extends WP_Menu_Item 
     390 */ 
     391function register_menu_item($menu_item_class) { 
     392        global $wp_menu_item_factory; 
     393 
     394        $wp_menu_item_factory->register($menu_item_class); 
     395} 
     396 
     397/** 
     398 * Unregister a menu_item 
     399 * 
     400 * Unregisters a WP_Menu_Item menu_item. Useful for unregistering default menu_items. 
     401 * Run within a function hooked to the menu_items_init action. 
     402 * 
     403 * @since 3.0.0 
     404 * 
     405 * @see WP_Menu_Item 
     406 * @see WP_Menu_Item_Factory 
     407 * @uses WP_Menu_Item_Factory 
     408 * 
     409 * @param string $menu_item_class The name of a class that extends WP_Menu_Item 
     410 */ 
     411function unregister_menu_item($menu_item_class) { 
     412        global $wp_menu_item_factory; 
     413 
     414        $wp_menu_item_factory->unregister($menu_item_class); 
     415} 
     416 
     417/** 
     418 * Creates multiple menus. 
     419 * 
     420 * If you wanted to quickly create multiple menus for a theme or internally. 
     421 * This function will allow you to do so. If you don't pass the 'name' and/or 
     422 * 'id' in $args, then they will be built for you. 
     423 * 
     424 * The default for the name is "Menu #", with '#' being replaced with the 
     425 * number the menu is currently when greater than one. If first menu, the 
     426 * name will be just "Menu". The default for id is "menu-" followed by the 
     427 * number the menu creation is currently at. 
     428 * 
     429 * @since 3.0.0 
     430 * 
     431 * @see register_menu() The second parameter is documented by register_menu() and is the same here. 
     432 * @uses parse_str() Converts a string to an array to be used in the rest of the function. 
     433 * @uses register_menu() Sends single menu information [name, id] to this 
     434 *      function to handle building the menu. 
     435 * 
     436 * @param int $number Number of menus to create. 
     437 * @param string|array $args Builds Menu based off of 'name' and 'id' values. 
     438 */ 
     439function register_menus($number = 1, $args = array()) { 
     440        global $wp_registered_menus; 
     441        $number = (int) $number; 
     442 
     443        if ( is_string($args) ) 
     444                parse_str($args, $args); 
     445 
     446        for ( $i=1; $i <= $number; $i++ ) { 
     447                $_args = $args; 
     448 
     449                if ( $number > 1 ) { 
     450                        $_args['name'] = isset($args['name']) ? sprintf($args['name'], $i) : sprintf(__('Menu %d'), $i); 
     451                } else { 
     452                        $_args['name'] = isset($args['name']) ? $args['name'] : __('Menu'); 
     453                } 
     454 
     455                if ( !isset($args['id']) ) { 
     456                        $n = count($wp_registered_menus); 
     457                        do { 
     458                                $n++; 
     459                                $_args['id'] = "menu-$n"; 
     460                        } while (isset($wp_registered_menus[$_args['id']])); 
     461                } 
     462 
     463                register_menu($_args); 
     464        } 
     465} 
     466 
     467/** 
     468 * Builds the definition for a single menu and returns the ID. 
     469 * 
     470 * The $args parameter takes either a string or an array with 'name' and 'id' 
     471 * contained in either usage. It will be noted that the values will be applied 
     472 * to all menus, so if creating more than one, it will be advised to allow 
     473 * for WordPress to create the defaults for you. 
     474 * 
     475 * Example for string would be <code>'name=whatever;id=whatever1'</code> and for 
     476 * the array it would be <code>array( 
     477 *    'name' => 'whatever', 
     478 *    'id' => 'whatever1')</code>. 
     479 * 
     480 * name - The name of the menu, which presumably the title which will be 
     481 *     displayed. 
     482 * id - The unique identifier by which the menu will be called by. 
     483 * before_menu_item - The content that will prepended to the menu_items when they are 
     484 *     displayed. 
     485 * after_menu_item - The content that will be appended to the menu_items when they are 
     486 *     displayed. 
     487 * before_title - The content that will be prepended to the title when displayed. 
     488 * after_title - the content that will be appended to the title when displayed. 
     489 * 
     490 * <em>Content</em> is assumed to be HTML and should be formatted as such, but 
     491 * doesn't have to be. 
     492 * 
     493 * @since 3.0.0 
     494 * @uses $wp_registered_menus Stores the new menu in this array by menu ID. 
     495 * @uses parse_str() Converts a string to an array to be used in the rest of the function. 
     496 * @usedby register_menus() 
     497 * 
     498 * @param string|array $args Builds Menu based off of 'name' and 'id' values 
     499 * @return string The menu id that was added. 
     500 */ 
     501function register_menu($args = array()) { 
     502        global $wp_registered_menus; 
     503 
     504        $i = count($wp_registered_menus) + 1; 
     505 
     506        $defaults = array( 
     507                'name' => sprintf(__('Menu %d'), $i ), 
     508                'id' => "menu-$i", 
     509                'description' => '', 
     510                'before_menu' => '<ul id="%1$s" class="menu %2$s">', 
     511                'after_menu' => "</ul>\n", 
     512        ); 
     513 
     514        $menu = wp_parse_args($args, $defaults); 
     515 
     516        $wp_registered_menus[$menu['id']] = $menu; 
     517 
     518        return $menu['id']; 
     519} 
     520 
     521/** 
     522 * Removes a menu from the list. 
     523 * 
     524 * @since 3.0.0 
     525 * 
     526 * @uses $wp_registered_menus Stores the new menu in this array by menu ID. 
     527 * 
     528 * @param string $name The ID of the menu when it was added. 
     529 */ 
     530function unregister_menu( $name ) { 
     531        global $wp_registered_menus; 
     532 
     533        if ( isset( $wp_registered_menus[$name] ) ) 
     534                unset( $wp_registered_menus[$name] ); 
     535} 
     536 
     537/** 
     538 * Register menu_item for use in menus. 
     539 * 
     540 * The default menu_item option is 'classname' that can be override. 
     541 * 
     542 * The function can also be used to unregister menu_items when $output_callback 
     543 * parameter is an empty string. 
     544 * 
     545 * @since 3.0.0 
     546 * 
     547 * @uses $wp_registered_menu_items Uses stored registered menu_items. 
     548 * @uses $wp_register_menu_item_defaults Retrieves menu_item defaults. 
     549 * 
     550 * @param int|string $id Menu_Item ID. 
     551 * @param string $name Menu_Item display title. 
     552 * @param callback $output_callback Run when menu_item is called. 
     553 * @param array|string Optional. $options Menu_Item Options. 
     554 * @param mixed $params,... Menu_Item parameters to add to menu_item. 
     555 * @return null Will return if $output_callback is empty after removing menu_item. 
     556 */ 
     557function wp_register_menu_item($id, $name, $output_callback, $options = array()) { 
     558        global $wp_registered_menu_items, $wp_registered_menu_item_controls, $wp_registered_menu_item_updates; 
     559 
     560        $id = strtolower($id); 
     561 
     562        if ( empty($output_callback) ) { 
     563                unset($wp_registered_menu_items[$id]); 
     564                return; 
     565        } 
     566 
     567        $id_base = _get_menu_item_id_base($id); 
     568        if ( !is_callable($output_callback) ) { 
     569                if ( isset($wp_registered_menu_item_controls[$id]) ) 
     570                        unset($wp_registered_menu_item_controls[$id]); 
     571 
     572                if ( isset($wp_registered_menu_item_updates[$id_base]) ) 
     573                        unset($wp_registered_menu_item_updates[$id_base]); 
     574 
     575                return; 
     576        } 
     577 
     578        $defaults = array('classname' => $output_callback); 
     579        $options = wp_parse_args($options, $defaults); 
     580        $menu_item = array( 
     581                'name' => $name, 
     582                'id' => $id, 
     583                'callback' => $output_callback, 
     584                'params' => array_slice(func_get_args(), 4) 
     585        ); 
     586        $menu_item = array_merge($menu_item, $options); 
     587 
     588        if ( is_callable($output_callback) && ( !isset($wp_registered_menu_items[$id]) || did_action( 'menu_items_init' ) ) ) 
     589                $wp_registered_menu_items[$id] = $menu_item; 
     590} 
     591 
     592/** 
     593 * Retrieve description for menu_item. 
     594 * 
     595 * When registering menu_items, the options can also include 'description' that 
     596 * describes the menu_item for display on the menu_item administration panel or 
     597 * in the theme. 
     598 * 
     599 * @since 3.0.0 
     600 * 
     601 * @param int|string $id Menu_Item ID. 
     602 * @return string Menu_Item description, if available. Null on failure to retrieve description. 
     603 */ 
     604function wp_menu_item_description( $id ) { 
     605        if ( !is_scalar($id) ) 
     606                return; 
     607 
     608        global $wp_registered_menu_items; 
     609 
     610        if ( isset($wp_registered_menu_items[$id]['description']) ) 
     611                return esc_html( $wp_registered_menu_items[$id]['description'] ); 
     612} 
     613 
     614/** 
     615 * Retrieve description for a menu. 
     616 * 
     617 * When registering menus a 'description' parameter can be included that 
     618 * describes the menu for display on the menu_item administration panel. 
     619 * 
     620 * @since 3.0.0 
     621 * 
     622 * @param int|string $id menu ID. 
     623 * @return string Menu description, if available. Null on failure to retrieve description. 
     624 */ 
     625function wp_menu_description( $id ) { 
     626        if ( !is_scalar($id) ) 
     627                return; 
     628 
     629        global $wp_registered_menus; 
     630 
     631        if ( isset($wp_registered_menus[$id]['description']) ) 
     632                return esc_html( $wp_registered_menus[$id]['description'] ); 
     633} 
     634 
     635 
     636/** 
     637 * Remove menu_item from menu. 
     638 * 
     639 * @since 3.0.0 
     640 * 
     641 * @param int|string $id Menu_Item ID. 
     642 */ 
     643function wp_unregister_menu_item($id) { 
     644        wp_register_menu_item($id, '', ''); 
     645        wp_unregister_menu_item_control($id); 
     646} 
     647 
     648/** 
     649 * Registers menu_item control callback for customizing options. 
     650 * 
     651 * The options contains the 'height', 'width', and 'id_base' keys. The 'height' 
     652 * option is never used. The 'width' option is the width of the fully expanded 
     653 * control form, but try hard to use the default width. The 'id_base' is for 
     654 * multi-menu_items (menu_items which allow multiple instances such as the text 
     655 * menu_item), an id_base must be provided. The menu_item id will end up looking like 
     656 * {$id_base}-{$unique_number}. 
     657 * 
     658 * @since 3.0.0 
     659 * 
     660 * @param int|string $id Menu ID. 
     661 * @param string $name Menu display name. 
     662 * @param callback $control_callback Run when menu is displayed. 
     663 * @param array|string $options Optional. Menu_Item options. See above long description. 
     664 * @param mixed $params,... Optional. Additional parameters to add to menu_item. 
     665 */ 
     666function wp_register_menu_item_control($id, $name, $control_callback, $options = array()) { 
     667        global $wp_registered_menu_item_controls, $wp_registered_menu_item_updates, $wp_registered_menu_items; 
     668 
     669        $id = strtolower($id); 
     670        $id_base = _get_menu_item_id_base($id); 
     671 
     672        if ( empty($control_callback) ) { 
     673                unset($wp_registered_menu_item_controls[$id]); 
     674                unset($wp_registered_menu_item_updates[$id_base]); 
     675                return; 
     676        } 
     677 
     678        if ( !is_callable($control_callback) ) { 
     679                if ( isset($wp_registered_menu_items[$id]) ) 
     680                        unset($wp_registered_menu_items[$id]); 
     681 
     682                return; 
     683        } 
     684 
     685        if ( isset($wp_registered_menu_item_controls[$id]) && !did_action( 'menu_items_init' ) ) 
     686                return; 
     687 
     688        $defaults = array('width' => 250, 'height' => 200 ); // height is never used 
     689        $options = wp_parse_args($options, $defaults); 
     690        $options['width'] = (int) $options['width']; 
     691        $options['height'] = (int) $options['height']; 
     692 
     693        $menu_item = array( 
     694                'name' => $name, 
     695                'id' => $id, 
     696                'callback' => $control_callback, 
     697                'params' => array_slice(func_get_args(), 4) 
     698        ); 
     699        $menu_item = array_merge($menu_item, $options); 
     700 
     701        $wp_registered_menu_item_controls[$id] = $menu_item; 
     702 
     703        if ( isset($wp_registered_menu_item_updates[$id_base]) ) 
     704                return; 
     705 
     706        if ( isset($menu_item['params'][0]['number']) ) 
     707                $menu_item['params'][0]['number'] = -1; 
     708 
     709        unset($menu_item['width'], $menu_item['height'], $menu_item['name'], $menu_item['id']); 
     710        $wp_registered_menu_item_updates[$id_base] = $menu_item; 
     711} 
     712 
     713function _register_menu_item_update_callback($id_base, $update_callback, $options = array()) { 
     714        global $wp_registered_menu_item_updates; 
     715 
     716        if ( isset($wp_registered_menu_item_updates[$id_base]) ) { 
     717                if ( empty($update_callback) ) 
     718                        unset($wp_registered_menu_item_updates[$id_base]); 
     719                return; 
     720        } 
     721 
     722        $menu_item = array( 
     723                'callback' => $update_callback, 
     724                'params' => array_slice(func_get_args(), 3) 
     725        ); 
     726 
     727        $menu_item = array_merge($menu_item, $options); 
     728        $wp_registered_menu_item_updates[$id_base] = $menu_item; 
     729} 
     730 
     731function _register_menu_item_form_callback($id, $name, $form_callback, $options = array()) { 
     732        global $wp_registered_menu_item_controls; 
     733 
     734        $id = strtolower($id); 
     735 
     736        if ( empty($form_callback) ) { 
     737                unset($wp_registered_menu_item_controls[$id]); 
     738                return; 
     739        } 
     740 
     741        if ( isset($wp_registered_menu_item_controls[$id]) && !did_action( 'menu_items_init' ) ) 
     742                return; 
     743 
     744        $defaults = array('width' => 250, 'height' => 200 ); 
     745        $options = wp_parse_args($options, $defaults); 
     746        $options['width'] = (int) $options['width']; 
     747        $options['height'] = (int) $options['height']; 
     748 
     749        $menu_item = array( 
     750                'name' => $name, 
     751                'id' => $id, 
     752                'callback' => $form_callback, 
     753                'params' => array_slice(func_get_args(), 4) 
     754        ); 
     755        $menu_item = array_merge($menu_item, $options); 
     756 
     757        $wp_registered_menu_item_controls[$id] = $menu_item; 
     758} 
     759 
     760/** 
     761 * Remove control callback for menu_item. 
     762 * 
     763 * @since 3.0.0 
     764 * @uses wp_register_menu_item_control() Unregisters by using empty callback. 
     765 * 
     766 * @param int|string $id Menu_Item ID. 
     767 */ 
     768function wp_unregister_menu_item_control($id) { 
     769        return wp_register_menu_item_control($id, '', ''); 
     770} 
     771 
     772/** 
     773 * Display dynamic menu. 
     774 * 
     775 * By default it displays the default menu or 'menu-1'. The 'menu-1' is 
     776 * not named by the theme, the actual name is '1', but 'menu-' is added to 
     777 * the registered menus for the name. If you named your menu 'after-post', 
     778 * then the parameter $index will still be 'after-post', but the lookup will be 
     779 * for 'menu-after-post'. 
     780 * 
     781 * It is confusing for the $index parameter, but just know that it should just 
     782 * work. When you register the menu in the theme, you will use the same name 
     783 * for this function or "Pay no heed to the man behind the curtain." Just accept 
     784 * it as an oddity of WordPress menu register and display. 
     785 * 
     786 * @since 3.0.0 
     787 * 
     788 * @param int|string $index Optional, default is 1. Name or ID of dynamic menu. 
     789 * @return bool True, if menu_item menu was found and called. False if not found or not called. 
     790 */ 
     791function dynamic_menu($index = 1) { 
     792        global $wp_registered_menus, $wp_registered_menu_items; 
     793 
     794        if ( is_int($index) ) { 
     795                $index = "menu-$index"; 
     796        } else { 
     797                $index = sanitize_title($index); 
     798                foreach ( (array) $wp_registered_menus as $key => $value ) { 
     799                        if ( sanitize_title($value['name']) == $index ) { 
     800                                $index = $key; 
     801                                break; 
     802                        } 
     803                } 
     804        } 
     805 
     806        $wp_menu_items = wp_get_menu_items(); 
     807 
     808        if ( empty($wp_registered_menus[$index]) || !array_key_exists($index, $wp_menu_items) || !is_array($wp_menu_items[$index]) || empty($wp_menu_items[$index]) ) 
     809                return false; 
     810 
     811        $menu = $wp_registered_menus[$index]; 
     812 
     813        $did_one = false; 
     814        foreach ( (array) $wp_menu_items[$index] as $id ) { 
     815 
     816                if ( !isset($wp_registered_menu_items[$id]) ) continue; 
     817 
     818                $params = array_merge( 
     819                        array( array_merge( $menu, array('menu_item_id' => $id, 'menu_item_name' => $wp_registered_menu_items[$id]['name']) ) ), 
     820                        (array) $wp_registered_menu_items[$id]['params'] 
     821                ); 
     822 
     823                // Substitute HTML id and class attributes into before_menu_item 
     824                $classname_ = ''; 
     825                foreach ( (array) $wp_registered_menu_items[$id]['classname'] as $cn ) { 
     826                        if ( is_string($cn) ) 
     827                                $classname_ .= '_' . $cn; 
     828                        elseif ( is_object($cn) ) 
     829                                $classname_ .= '_' . get_class($cn); 
     830                } 
     831                $classname_ = ltrim($classname_, '_'); 
     832                $params[0]['before_menu_item'] = sprintf($params[0]['before_menu'], $id, $classname_); 
     833 
     834                $params = apply_filters( 'dynamic_menu_params', $params ); 
     835 
     836                $callback = $wp_registered_menu_items[$id]['callback']; 
     837 
     838                if ( is_callable($callback) ) { 
     839                        call_user_func_array($callback, $params); 
     840                        $did_one = true; 
     841                } 
     842        } 
     843 
     844        return $did_one; 
     845} 
     846 
     847/** 
     848 * Whether menu_item is displayied on the front-end. 
     849 * 
     850 * Either $callback or $id_base can be used 
     851 * $id_base is the first argument when extending WP_Menu_Item class 
     852 * Without the optional $menu_item_id parameter, returns the ID of the first menu 
     853 * in which the first instance of the menu_item with the given callback or $id_base is found. 
     854 * With the $menu_item_id parameter, returns the ID of the menu where 
     855 * the menu_item with that callback/$id_base AND that ID is found. 
     856 * 
     857 * NOTE: $menu_item_id and $id_base are the same for single menu_items. To be effective 
     858 * this function has to run after menu_items have initialized, at action 'init' or later. 
     859 * 
     860 * @since 3.0.0 
     861 * 
     862 * @param callback Optional, Menu_Item callback to check. 
     863 * @param int $menu_item_id Optional, but needed for checking. Menu_Item ID. 
     864 * @param string $id_base Optional, the base ID of a menu_item created by extending WP_Menu_Item. 
     865 * @param bool $skip_inactive Optional, whether to check in 'wp_inactive_menu_items'. 
     866 * @return mixed false if menu_item is not active or id of menu in which the menu_item is active. 
     867 */ 
     868function is_active_menu_item($callback = false, $menu_item_id = false, $id_base = false, $skip_inactive = true) { 
     869        global $wp_registered_menu_items; 
     870 
     871        $wp_menu_items = wp_get_menu_items(); 
     872 
     873        if ( is_array($wp_menu_items) ) { 
     874                foreach ( $wp_menu_items as $menu => $menu_items ) { 
     875                        if ( $skip_inactive && 'wp_inactive_menu_items' == $menu ) 
     876                                continue; 
     877 
     878                        if ( is_array($menu_items) ) { 
     879                                foreach ( $menu_items as $menu_item ) { 
     880                                        if ( ( $callback && isset($wp_registered_menu_items[$menu_item]['callback']) && $wp_registered_menu_items[$menu_item]['callback'] == $callback ) || ( $id_base && _get_menu_item_id_base($menu_item) == $id_base ) ) { 
     881                                                if ( !$menu_item_id || $menu_item_id == $wp_registered_menu_items[$menu_item]['id'] ) 
     882                                                        return $menu; 
     883                                        } 
     884                                } 
     885                        } 
     886                } 
     887        } 
     888        return false; 
     889} 
     890 
     891/** 
     892 * Whether the dynamic menu is enabled and used by theme. 
     893 * 
     894 * @since 3.0.0 
     895 * 
     896 * @return bool True, if using menu_items. False, if not using menu_items. 
     897 */ 
     898function is_dynamic_menu() { 
     899        global $wp_registered_menu_items, $wp_registered_menus; 
     900        $wp_menu_items = get_option('wp_menu_items'); 
     901        foreach ( (array) $wp_registered_menus as $index => $menu ) { 
     902                if ( count($wp_menu_items[$index]) ) { 
     903                        foreach ( (array) $wp_menu_items[$index] as $menu_item ) 
     904                                if ( array_key_exists($menu_item, $wp_registered_menu_items) ) 
     905                                        return true; 
     906                } 
     907        } 
     908        return false; 
     909} 
     910 
     911/** 
     912 * Whether a menu is in use. 
     913 * 
     914 * @since 3.0 
     915 * 
     916 * @param mixed $index, menu name, id or number to check. 
     917 * @return bool true if the menu is in use, false otherwise. 
     918 */ 
     919function is_active_menu( $index ) { 
     920        $index = ( is_int($index) ) ? "menu-$index" : sanitize_title($index); 
     921        $wp_menu_items = wp_get_menu_items(); 
     922        if ( isset($wp_menu_items[$index]) && !empty($wp_menu_items[$index]) ) 
     923                return true; 
     924 
     925        return false; 
     926} 
     927 
     928/* Internal Functions */ 
     929 
     930/** 
     931 * Retrieve full list of menus and their menu_items. 
     932 * 
     933 * Will upgrade menu menu_item list, if needed. Will also save updated list, if 
     934 * needed. 
     935 * 
     936 * @since 3.0.0 
     937 * @access private 
     938 * 
     939 * @return array Upgraded list of menu_items to version 3 array format when called from the admin. 
     940 */ 
     941function wp_get_menu_items() { 
     942        global $wp_registered_menu_items, $wp_registered_menus, $_wp_menu_items; 
     943 
     944        // If loading from front page, consult $_wp_menu_items rather than options 
     945        // to see if wp_convert_menu_item_settings() has made manipulations in memory. 
     946        if ( !is_admin() ) { 
     947                if ( empty($_wp_menu_items) ) 
     948                        $_wp_menu_items = get_option('wp_menu_items', array()); 
     949 
     950                $wp_menu_items = $_wp_menu_items; 
     951        } else { 
     952                $wp_menu_items = get_option('wp_menu_items', array()); 
     953                $_wp_menu_items = array(); 
     954 
     955                if ( isset($wp_menu_items['wp_inactive_menu_items']) || empty($wp_menu_items) ) 
     956                        $wp_menu_items['array_version'] = 3; 
     957                elseif ( !isset($wp_menu_items['array_version']) ) 
     958                        $wp_menu_items['array_version'] = 1; 
     959 
     960                switch ( $wp_menu_items['array_version'] ) { 
     961                        case 1 : 
     962                                foreach ( (array) $wp_menu_items as $index => $menu ) 
     963                                if ( is_array($menu) ) 
     964                                foreach ( (array) $menu as $i => $name ) { 
     965                                        $id = strtolower($name); 
     966                                        if ( isset($wp_registered_menu_items[$id]) ) { 
     967                                                $_wp_menu_items[$index][$i] = $id; 
     968                                                continue; 
     969                                        } 
     970                                        $id = sanitize_title($name); 
     971                                        if ( isset($wp_registered_menu_items[$id]) ) { 
     972                                                $_wp_menu_items[$index][$i] = $id; 
     973                                                continue; 
     974                                        } 
     975 
     976                                        $found = false; 
     977 
     978                                        foreach ( $wp_registered_menu_items as $menu_item_id => $menu_item ) { 
     979                                                if ( strtolower($menu_item['name']) == strtolower($name) ) { 
     980                                                        $_wp_menu_items[$index][$i] = $menu_item['id']; 
     981                                                        $found = true; 
     982                                                        break; 
     983                                                } elseif ( sanitize_title($menu_item['name']) == sanitize_title($name) ) { 
     984                                                        $_wp_menu_items[$index][$i] = $menu_item['id']; 
     985                                                        $found = true; 
     986                                                        break; 
     987                                                } 
     988                                        } 
     989 
     990                                        if ( $found ) 
     991                                                continue; 
     992 
     993                                        unset($_wp_menu_items[$index][$i]); 
     994                                } 
     995                                $_wp_menu_items['array_version'] = 2; 
     996                                $wp_menu_items = $_wp_menu_items; 
     997                                unset($_wp_menu_items); 
     998 
     999                        case 2 : 
     1000                                $menus = array_keys( $wp_registered_menus ); 
     1001                                if ( !empty( $menus ) ) { 
     1002                                        // Move the known-good ones first 
     1003                                        foreach ( (array) $menus as $id ) { 
     1004                                                if ( array_key_exists( $id, $wp_menu_items ) ) { 
     1005                                                        $_wp_menu_items[$id] = $wp_menu_items[$id]; 
     1006                                                        unset($wp_menu_items[$id], $menus[$id]); 
     1007                                                } 
     1008                                        } 
     1009 
     1010                                        // move the rest to wp_inactive_menu_items 
     1011                                        if ( !isset($_wp_menu_items['wp_inactive_menu_items']) ) 
     1012                                                $_wp_menu_items['wp_inactive_menu_items'] = array(); 
     1013 
     1014                                        if ( !empty($wp_menu_items) ) { 
     1015                                                foreach ( $wp_menu_items as $lost => $val ) { 
     1016                                                        if ( is_array($val) ) 
     1017                                                                $_wp_menu_items['wp_inactive_menu_items'] = array_merge( (array) $_wp_menu_items['wp_inactive_menu_items'], $val ); 
     1018                                                } 
     1019                                        } 
     1020 
     1021                                        $wp_menu_items = $_wp_menu_items; 
     1022                                        unset($_wp_menu_items); 
     1023                                } 
     1024                } 
     1025        } 
     1026 
     1027        if ( isset($wp_menu_items['array_version']) ) 
     1028                unset($wp_menu_items['array_version']); 
     1029 
     1030        $wp_menu_items = apply_filters('wp_menu_items', $wp_menu_items); 
     1031        return $wp_menu_items; 
     1032} 
     1033 
     1034/** 
     1035 * Set the menu menu_item option to update menus. 
     1036 * 
     1037 * @since 3.0.0 
     1038 * @access private 
     1039 * 
     1040 * @param array $wp_menu_items Menu menu_items and their settings. 
     1041 */ 
     1042function wp_set_menu_items( $wp_menu_items ) { 
     1043        if ( !isset( $wp_menu_items['array_version'] ) ) 
     1044                $wp_menu_items['array_version'] = 3; 
     1045        update_option( 'wp_menu_items', $wp_menu_items ); 
     1046} 
     1047 
     1048/** 
     1049 * Retrieve default registered menus list. 
     1050 * 
     1051 * @since 3.0.0 
     1052 * @access private 
     1053 * 
     1054 * @return array 
     1055 */ 
     1056function wp_get_menu_item_defaults() { 
     1057        global $wp_registered_menus; 
     1058 
     1059        $defaults = array(); 
     1060 
     1061        foreach ( (array) $wp_registered_menus as $index => $menu ) 
     1062                $defaults[$index] = array(); 
     1063 
     1064        return $defaults; 
     1065} 
     1066 
     1067/** 
     1068 * Private 
     1069 */ 
     1070function _get_menu_item_id_base($id) { 
     1071        return preg_replace( '/-[0-9]+$/', '', $id ); 
     1072} 
     1073 
     1074// Initialization code 
     1075 
     1076/*ignore*/ 
     1077global $wp_menu_item_factory; 
     1078 
     1079/** 
     1080 * WordPress Menu Item Factory Object 
     1081 * @global object $wp_menu_item_factory 
     1082 * @since 3.0 
     1083 */ 
     1084$wp_menu_item_factory =& new WP_Menu_Item_Factory(); 
     1085 
  • wp-includes/script-loader.php

     
    326326                $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), '20090824' ); 
    327327                $scripts->add_data( 'admin-widgets', 'group', 1 ); 
    328328 
     329                $scripts->add( 'admin-menus', "/wp-admin/js/menus$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), '20090824' ); 
     330                $scripts->add_data( 'admin-menus', 'group', 1 ); 
     331 
    329332                $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array( 'jquery' ), '20090422' ); 
    330333                $scripts->add_data( 'word-count', 'group', 1 ); 
    331334                $scripts->localize( 'word-count', 'wordCountL10n', array( 
     
    426429 
    427430        $suffix = defined('STYLE_DEBUG') && STYLE_DEBUG ? '.dev' : ''; 
    428431 
    429         $rtl_styles = array( 'wp-admin', 'global', 'colors', 'dashboard', 'ie', 'install', 'login', 'media', 'theme-editor', 'upload', 'widgets', 'press-this', 'plugin-install', 'farbtastic' ); 
     432        $rtl_styles = array( 'wp-admin', 'global', 'colors', 'dashboard', 'ie', 'install', 'login', 'media', 'theme-editor', 'upload', 'widgets', 'menus', 'press-this', 'plugin-install', 'farbtastic' ); 
    430433 
    431434        // all colors stylesheets need to have the same query strings (cache manifest compat) 
    432435        $colors_version = '20091227'; 
     
    448451        $styles->add( 'global', "/wp-admin/css/global$suffix.css", array(), '20100108' ); 
    449452        $styles->add( 'media', "/wp-admin/css/media$suffix.css", array(), '20091029' ); 
    450453        $styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array(), '20091118' ); 
     454        $styles->add( 'menus', "/wp-admin/css/menus$suffix.css", array(), '20100109' ); 
    451455        $styles->add( 'dashboard', "/wp-admin/css/dashboard$suffix.css", array(), '20091211' ); 
    452456        $styles->add( 'install', "/wp-admin/css/install$suffix.css", array(), '20090514' ); 
    453457        $styles->add( 'theme-editor', "/wp-admin/css/theme-editor$suffix.css", array(), '20090625' ); 
  • wp-content/themes/default/functions.php

     
    1717        )); 
    1818} 
    1919 
     20// Dynamic menu support 
     21add_theme_support('menus'); 
     22register_menu(array( 
     23        'before_menu' => '<ul id="%1$s" class="menu %2$s">', 
     24        'after_menu' => '</ul>', 
     25)); 
     26 
    2027/** @ignore */ 
    2128function kubrick_head() { 
    2229        $head = "<style type='text/css'>\n<!--"; 
  • wp-settings.php

     
    401401require (ABSPATH . WPINC . '/media.php'); 
    402402require (ABSPATH . WPINC . '/http.php'); 
    403403require (ABSPATH . WPINC . '/widgets.php'); 
     404require (ABSPATH . WPINC . '/menus.php'); 
    404405 
    405406if ( is_multisite() ) { 
    406407        require_once( ABSPATH . WPINC . '/ms-functions.php' ); 
     
    739740// Load in support for template functions which the theme supports 
    740741require_if_theme_supports( 'post-thumbnails', ABSPATH . WPINC . '/post-thumbnail-template.php' ); 
    741742 
     743// Menus init 
     744if ( current_theme_supports( 'menus' ) ) { 
     745        if ( apply_filters('load_default_menu_items', true) ) 
     746                require( ABSPATH . WPINC . '/default-menu-items.php' ); 
     747 
     748        require (ABSPATH . WPINC . '/menu-template.php'); 
     749 
     750        function _wp_add_menus_menu() { 
     751                global $submenu; 
     752                $submenu['themes.php'][8] = array( __( 'Menus' ), 'switch_themes', 'menus.php' ); 
     753                ksort( $submenu['themes.php'], SORT_NUMERIC ); 
     754        } 
     755        add_action( '_admin_menu', '_wp_add_menus_menu' ); 
     756} 
     757 
     758 
    742759/** 
    743760 * Runs just before PHP shuts down execution. 
    744761 * 
  • wp-admin/admin-ajax.php

     
    13791379 
    13801380        die(); 
    13811381        break; 
     1382case 'menu_items-order' : 
     1383        check_ajax_referer( 'save-menu-items', 'savemenu_items' ); 
     1384 
     1385        if ( !current_user_can('switch_themes') ) 
     1386                die('-1'); 
     1387 
     1388        unset( $_POST['savemenu_items'], $_POST['action'] ); 
     1389 
     1390        // save menu_items order for all menus 
     1391        if ( is_array($_POST['menus']) ) { 
     1392                $menus = array(); 
     1393                foreach ( $_POST['menus'] as $key => $val ) { 
     1394                        $sb = array(); 
     1395                        if ( !empty($val) ) { 
     1396                                $val = explode(',', $val); 
     1397                                foreach ( $val as $k => $v ) { 
     1398                                        if ( strpos($v, 'menu_item-') === false ) 
     1399                                                continue; 
     1400 
     1401                                        $sb[$k] = substr($v, strpos($v, '_') + 1); 
     1402                                } 
     1403                        } 
     1404                        $menus[$key] = $sb; 
     1405                } 
     1406                wp_set_menu_items($menus); 
     1407                die('1'); 
     1408        } 
     1409 
     1410        die('-1'); 
     1411        break; 
     1412case 'save-menu_item' : 
     1413        check_ajax_referer( 'save-menu-items', 'savemenu_items' ); 
     1414 
     1415        if ( !current_user_can('switch_themes') || !isset($_POST['id_base']) ) 
     1416                die('-1'); 
     1417 
     1418        unset( $_POST['savemenu_items'], $_POST['action'] ); 
     1419 
     1420        do_action('load-menus.php'); 
     1421        do_action('menus.php'); 
     1422        do_action('menu_admin_setup'); 
     1423 
     1424        $id_base = $_POST['id_base']; 
     1425        $menu_item_id = $_POST['menu_item-id']; 
     1426        $menu_id = $_POST['menu']; 
     1427        $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0; 
     1428        $settings = isset($_POST['menu_item-' . $id_base]) && is_array($_POST['menu_item-' . $id_base]) ? $_POST['menu_item-' . $id_base] : false; 
     1429        $error = '<p>' . __('An error has occured. Please reload the page and try again.') . '</p>'; 
     1430 
     1431        $menus = wp_get_menu_items(); 
     1432        $menu = isset($menus[$menu_id]) ? $menus[$menu_id] : array(); 
     1433 
     1434        // delete 
     1435        if ( isset($_POST['delete_menu_item']) && $_POST['delete_menu_item'] ) { 
     1436 
     1437                if ( !isset($wp_registered_menu_items[$menu_item_id]) ) 
     1438                        die($error); 
     1439 
     1440                $menu = array_diff( $menu, array($menu_item_id) ); 
     1441                $_POST = array('menu' => $menu_id, 'menu_item-' . $id_base => array(), 'the-menu_item-id' => $menu_item_id, 'delete_menu_item' => '1'); 
     1442        } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) { 
     1443                if ( !$multi_number ) 
     1444                        die($error); 
     1445 
     1446                $_POST['menu_item-' . $id_base] = array( $multi_number => array_shift($settings) ); 
     1447                $menu_item_id = $id_base . '-' . $multi_number; 
     1448                $menu[] = $menu_item_id; 
     1449        } 
     1450        $_POST['menu_item-id'] = $menu; 
     1451 
     1452        foreach ( (array) $wp_registered_menu_item_updates as $name => $control ) { 
     1453 
     1454                if ( $name == $id_base ) { 
     1455                        if ( !is_callable( $control['callback'] ) ) 
     1456                                continue; 
     1457 
     1458                        ob_start(); 
     1459                                call_user_func_array( $control['callback'], $control['params'] ); 
     1460                        ob_end_clean(); 
     1461                        break; 
     1462                } 
     1463        } 
     1464 
     1465        if ( isset($_POST['delete_menu_item']) && $_POST['delete_menu_item'] ) { 
     1466                $menus[$menu_id] = $menu; 
     1467                wp_set_menu_items($menus); 
     1468                echo "deleted:$menu_item_id"; 
     1469                die(); 
     1470        } 
     1471 
     1472        if ( !empty($_POST['add_new']) ) 
     1473                die(); 
     1474 
     1475        if ( $form = $wp_registered_menu_item_controls[$menu_item_id] ) 
     1476                call_user_func_array( $form['callback'], $form['params'] ); 
     1477 
     1478        die(); 
     1479        break; 
    13821480case 'image-editor': 
    13831481        $attachment_id = intval($_POST['postid']); 
    13841482        if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) ) 
  • wp-admin/includes/menus.php

     
     1<?php 
     2/** 
     3 * WordPress Menus Administration API 
     4 * 
     5 * @package WordPress 
     6 * @subpackage Administration 
     7 */ 
     8 
     9/** 
     10 * Display list of the available menu_items, either all or matching search. 
     11 * 
     12 * The search parameter are search terms separated by spaces. 
     13 * 
     14 * @since 3.0 
     15 * 
     16 * @param string $show Optional, default is all. What to display, can be 'all', 'unused', or 'used'. 
     17 * @param string $_search Optional. Search for menu_items. Should be unsanitized. 
     18 */ 
     19function wp_list_menu_items() { 
     20        global $wp_registered_menu_items, $menus_menu_items, $wp_registered_menu_item_controls; 
     21 
     22        $sort = $wp_registered_menu_items; 
     23        usort( $sort, create_function( '$a, $b', 'return strnatcasecmp( $a["name"], $b["name"] );' ) ); 
     24        $done = array(); 
     25 
     26        foreach ( $sort as $menu_item ) { 
     27                if ( in_array( $menu_item['callback'], $done, true ) ) // We already showed this multi-menu_item 
     28                        continue; 
     29 
     30                $menu = is_active_menu_item( $menu_item['callback'], $menu_item['id'], false, false ); 
     31                $done[] = $menu_item['callback']; 
     32 
     33                if ( ! isset( $menu_item['params'][0] ) ) 
     34                        $menu_item['params'][0] = array(); 
     35 
     36                $args = array( 'menu_item_id' => $menu_item['id'], 'menu_item_name' => $menu_item['name'], '_display' => 'template' ); 
     37 
     38                if ( isset($wp_registered_menu_item_controls[$menu_item['id']]['id_base']) && isset($menu_item['params'][0]['number']) ) { 
     39                        $id_base = $wp_registered_menu_item_controls[$menu_item['id']]['id_base']; 
     40                        $args['_temp_id'] = "$id_base-__i__"; 
     41                        $args['_multi_num'] = next_menu_item_id_number($id_base); 
     42                        $args['_add'] = 'multi'; 
     43                } else { 
     44                        $args['_add'] = 'single'; 
     45                        if ( $menu ) 
     46                                $args['_hide'] = '1'; 
     47                } 
     48 
     49                $args = wp_list_menu_item_controls_dynamic_menu( array( 0 => $args, 1 => $menu_item['params'][0] ) ); 
     50                call_user_func_array( 'wp_menu_item_control', $args ); 
     51        } 
     52} 
     53 
     54/** 
     55 * Show the menu_items and their settings for a menu. 
     56 * Used in the the admin menu_item config screen. 
     57 * 
     58 * @since 3.0 
     59 * 
     60 * @param string $menu id slug of the menu 
     61 */ 
     62function wp_list_menu_item_controls( $menu ) { 
     63        add_filter( 'dynamic_menu_params', 'wp_list_menu_item_controls_dynamic_menu' ); 
     64 
     65        echo "<div id='$menu' class='menu_items-sortables'>\n"; 
     66 
     67        $description = wp_menu_description( $menu ); 
     68 
     69        if ( !empty( $description ) ) { 
     70                echo "<div class='menu-description'>\n"; 
     71                echo "\t<p class='description'>$description</p>";  
     72                echo "</div>\n"; 
     73        } 
     74 
     75        dynamic_menu( $menu ); 
     76        echo "</div>\n"; 
     77} 
     78 
     79/** 
     80 * {@internal Missing Short Description}} 
     81 * 
     82 * @since 3.0 
     83 * 
     84 * @param array $params 
     85 * @return array 
     86 */ 
     87function wp_list_menu_item_controls_dynamic_menu( $params ) { 
     88        global $wp_registered_menu_items; 
     89        static $i = 0; 
     90        $i++; 
     91 
     92        $menu_item_id = $params[0]['menu_item_id']; 
     93        $id = isset($params[0]['_temp_id']) ? $params[0]['_temp_id'] : $menu_item_id; 
     94        $hidden = isset($params[0]['_hide']) ? ' style="display:none;"' : ''; 
     95 
     96        $params[0]['before_menu_item'] = "<div id='menu_item-${i}_$id' class='menu_item'$hidden>"; 
     97        $params[0]['after_menu_item'] = "</div>"; 
     98        $params[0]['before_title'] = "%BEG_OF_TITLE%"; // deprecated 
     99        $params[0]['after_title'] = "%END_OF_TITLE%"; // deprecated 
     100        if ( is_callable( $wp_registered_menu_items[$menu_item_id]['callback'] ) ) { 
     101                $wp_registered_menu_items[$menu_item_id]['_callback'] = $wp_registered_menu_items[$menu_item_id]['callback']; 
     102                $wp_registered_menu_items[$menu_item_id]['callback'] = 'wp_menu_item_control'; 
     103        } 
     104 
     105        return $params; 
     106} 
     107 
     108function next_menu_item_id_number($id_base) { 
     109        global $wp_registered_menu_items; 
     110        $number = 1; 
     111 
     112        foreach ( $wp_registered_menu_items as $menu_item_id => $menu_item ) { 
     113                if ( preg_match( '/' . $id_base . '-([0-9]+)$/', $menu_item_id, $matches ) ) 
     114                        $number = max($number, $matches[1]); 
     115        } 
     116        $number++; 
     117 
     118        return $number; 
     119} 
     120 
     121/** 
     122 * Meta menu_item used to display the control form for a menu_item. 
     123 * 
     124 * Called from dynamic_menu(). 
     125 * 
     126 * @since 3.0 
     127 * 
     128 * @param array $menu_args 
     129 * @return array 
     130 */ 
     131function wp_menu_item_control( $menu_args ) { 
     132        global $wp_registered_menu_items, $wp_registered_menu_item_controls, $menus_menu_items; 
     133 
     134        $menu_item_id = $menu_args['menu_item_id']; 
     135        $menu_id = isset($menu_args['id']) ? $menu_args['id'] : false; 
     136        $key = $menu_id ? array_search( $menu_item_id, $menus_menu_items[$menu_id] ) : '-1'; // position of menu_item in menu 
     137        $control = isset($wp_registered_menu_item_controls[$menu_item_id]) ? $wp_registered_menu_item_controls[$menu_item_id] : array(); 
     138        $menu_item = $wp_registered_menu_items[$menu_item_id]; 
     139 
     140        $id_format = $menu_item['id']; 
     141        $menu_item_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : ''; 
     142        $id_base = isset($control['id_base']) ? $control['id_base'] : $menu_item_id; 
     143        $multi_number = isset($menu_args['_multi_num']) ? $menu_args['_multi_num'] : ''; 
     144        $add_new = isset($menu_args['_add']) ? $menu_args['_add'] : ''; 
     145 
     146        $query_arg = array( 'editmenu_item' => $menu_item['id'] ); 
     147        if ( $add_new ) { 
     148                $query_arg['addnew'] = 1; 
     149                if ( $multi_number ) { 
     150                        $query_arg['num'] = $multi_number; 
     151                        $query_arg['base'] = $id_base; 
     152                } 
     153        } else { 
     154                $query_arg['menu'] = $menu_id; 
     155                $query_arg['key'] = $key; 
     156        } 
     157 
     158        // We aren't showing a menu_item control, we're outputing a template for a mult-menu_item control 
     159        if ( isset($menu_args['_display']) && 'template' == $menu_args['_display'] && $menu_item_number ) { 
     160                // number == -1 implies a template where id numbers are replaced by a generic '__i__' 
     161                $control['params'][0]['number'] = -1; 
     162                // with id_base menu_item id's are constructed like {$id_base}-{$id_number} 
     163                if ( isset($control['id_base']) ) 
     164                        $id_format = $control['id_base'] . '-__i__'; 
     165        } 
     166 
     167        $wp_registered_menu_items[$menu_item_id]['callback'] = $wp_registered_menu_items[$menu_item_id]['_callback']; 
     168        unset($wp_registered_menu_items[$menu_item_id]['_callback']); 
     169 
     170        $menu_item_title = esc_html( strip_tags( $menu_args['menu_item_name'] ) ); 
     171        $has_form = 'noform'; 
     172 
     173        echo $menu_args['before_menu_item']; ?> 
     174        <div class="menu_item-top"> 
     175        <div class="menu_item-title-action"> 
     176                <a class="menu_item-action hide-if-no-js" href="#available-menu_items"></a> 
     177                <a class="menu_item-control-edit hide-if-js" href="<?php echo esc_url( add_query_arg( $query_arg ) ); ?>"><span class="edit"><?php _e('Edit'); ?></span><span class="add"><?php _e('Add'); ?></span></a> 
     178        </div> 
     179        <div class="menu_item-title"><h4><?php echo $menu_item_title ?><span class="in-menu_item-title"></span></h4></div> 
     180        </div> 
     181 
     182        <div class="menu_item-inside"> 
     183        <form action="" method="post"> 
     184        <div class="menu_item-content"> 
     185<?php 
     186        if ( isset($control['callback']) ) 
     187                $has_form = call_user_func_array( $control['callback'], $control['params'] ); 
     188        else 
     189                echo "\t\t<p>" . __('There are no options for this menu_item.') . "</p>\n"; ?> 
     190        </div> 
     191        <input type="hidden" name="menu_item-id" class="menu_item-id" value="<?php echo esc_attr($id_format); ?>" /> 
     192        <input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" /> 
     193        <input type="hidden" name="menu_item-width" class="menu_item-width" value="<?php if (isset( $control['width'] )) echo esc_attr($control['width']); ?>" /> 
     194        <input type="hidden" name="menu_item-height" class="menu_item-height" value="<?php if (isset( $control['height'] )) echo esc_attr($control['height']); ?>" /> 
     195        <input type="hidden" name="menu_item_number" class="menu_item_number" value="<?php echo esc_attr($menu_item_number); ?>" /> 
     196        <input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" /> 
     197        <input type="hidden" name="add_new" class="add_new" value="<?php echo esc_attr($add_new); ?>" /> 
     198 
     199        <div class="menu_item-control-actions"> 
     200                <div class="alignleft"> 
     201                <a class="menu_item-control-remove" href="#remove"><?php _e('Delete'); ?></a> | 
     202                <a class="menu_item-control-close" href="#close"><?php _e('Close'); ?></a> 
     203                </div> 
     204                <div class="alignright<?php if ( 'noform' === $has_form ) echo ' menu_item-control-noform'; ?>"> 
     205                <img src="images/wpspin_light.gif" class="ajax-feedback " title="" alt="" /> 
     206                <input type="submit" name="savemenu_item" class="button-primary menu_item-control-save" value="<?php esc_attr_e('Save'); ?>" /> 
     207                </div> 
     208                <br class="clear" /> 
     209        </div> 
     210        </form> 
     211        </div> 
     212 
     213        <div class="menu_item-description"> 
     214<?php echo ( $menu_item_description = wp_menu_item_description($menu_item_id) ) ? "$menu_item_description\n" : "$menu_item_title\n"; ?> 
     215        </div> 
     216<?php 
     217        echo $menu_args['after_menu_item']; 
     218        return $menu_args; 
     219} 
     220 
  • wp-admin/js/menus.dev.js

     
     1(function($) { 
     2        window.wpMenus = { 
     3 
     4        init : function() { 
     5                var rem, menus = $('div.menu_items-sortables'); 
     6 
     7                $('#menu_items-right').children('.menu_items-holder-wrap').children('.menu-name').click(function(){ 
     8                        var c = $(this).siblings('.menu_items-sortables'), p = $(this).parent(); 
     9                        if ( !p.hasClass('closed') ) { 
     10                                c.sortable('disable'); 
     11                                p.addClass('closed'); 
     12                        } else { 
     13                                p.removeClass('closed'); 
     14                                c.sortable('enable').sortable('refresh'); 
     15                        } 
     16                }); 
     17 
     18                $('#menu_items-left').children('.menu_items-holder-wrap').children('.menu-name').click(function() { 
     19                        $(this).siblings('.menu_item-holder').parent().toggleClass('closed'); 
     20                }); 
     21 
     22                menus.not('#wp_inactive_menu_items').each(function(){ 
     23                        var h = 50, H = $(this).children('.menu_item').length; 
     24                        h = h + parseInt(H * 48, 10); 
     25                        $(this).css( 'minHeight', h + 'px' ); 
     26                }); 
     27 
     28                $('a.menu_item-action').live('click', function(){ 
     29                        var css = {}, menu_item = $(this).closest('div.menu_item'), inside = menu_item.children('.menu_item-inside'), w = parseInt( menu_item.find('input.menu_item-width').val(), 10 ); 
     30                         
     31                        if ( inside.is(':hidden') ) { 
     32                                if ( w > 250 && inside.closest('div.menu_items-sortables').length ) { 
     33                                        css['width'] = w + 30 + 'px'; 
     34                                        if ( inside.closest('div.menu_item-liquid-right').length ) 
     35                                                css['marginLeft'] = 235 - w + 'px'; 
     36                                        menu_item.css(css); 
     37                                } 
     38                                wpMenus.fixLabels(menu_item); 
     39                                inside.slideDown('fast'); 
     40                        } else { 
     41                                inside.slideUp('fast', function() { 
     42                                        menu_item.css({'width':'','marginLeft':''}); 
     43                                }); 
     44                        } 
     45                        return false; 
     46                }); 
     47 
     48                $('input.menu_item-control-save').live('click', function(){ 
     49                        wpMenus.save( $(this).closest('div.menu_item'), 0, 1, 0 ); 
     50                        return false; 
     51                }); 
     52 
     53                $('a.menu_item-control-remove').live('click', function(){ 
     54                        wpMenus.save( $(this).closest('div.menu_item'), 1, 1, 0 ); 
     55                        return false; 
     56                }); 
     57 
     58                $('a.menu_item-control-close').live('click', function(){ 
     59                        wpMenus.close( $(this).closest('div.menu_item') ); 
     60                        return false; 
     61                }); 
     62 
     63                menus.children('.menu_item').each(function() { 
     64                        wpMenus.appendTitle(this); 
     65                        if ( $('p.menu_item-error', this).length ) 
     66                                $('a.menu_item-action', this).click(); 
     67                }); 
     68 
     69                $('#menu_item-list').children('.menu_item').draggable({ 
     70                        connectToSortable: 'div.menu_items-sortables', 
     71                        handle: '> .menu_item-top > .menu_item-title', 
     72                        distance: 2, 
     73                        helper: 'clone', 
     74                        zIndex: 5, 
     75                        containment: 'document', 
     76                        start: function(e,ui) { 
     77                                wpMenus.fixWebkit(1); 
     78                                ui.helper.find('div.menu_item-description').hide(); 
     79                        }, 
     80                        stop: function(e,ui) { 
     81                                if ( rem ) 
     82                                        $(rem).hide(); 
     83                                rem = ''; 
     84                                wpMenus.fixWebkit(); 
     85                        } 
     86                }); 
     87 
     88                menus.sortable({ 
     89                        placeholder: 'menu_item-placeholder', 
     90                        items: '> .menu_item', 
     91                        handle: '> .menu_item-top > .menu_item-title', 
     92                        cursor: 'move', 
     93                        distance: 2, 
     94                        containment: 'document', 
     95                        start: function(e,ui) { 
     96                                wpMenus.fixWebkit(1); 
     97                                ui.item.children('.menu_item-inside').hide(); 
     98                                ui.item.css({'marginLeft':'','width':''}); 
     99                        }, 
     100                        stop: function(e,ui) { 
     101                                if ( ui.item.hasClass('ui-draggable') ) 
     102                                        ui.item.draggable('destroy'); 
     103 
     104                                if ( ui.item.hasClass('deleting') ) { 
     105                                        wpMenus.save( ui.item, 1, 0, 1 ); // delete menu_item 
     106                                        ui.item.remove(); 
     107                                        return; 
     108                                } 
     109 
     110                                var add = ui.item.find('input.add_new').val(), 
     111                                        n = ui.item.find('input.multi_number').val(), 
     112                                        id = ui.item.attr('id'), 
     113                                        sb = $(this).attr('id'); 
     114 
     115                                ui.item.css({'marginLeft':'','width':''}); 
     116                                wpMenus.fixWebkit(); 
     117                                if ( add ) { 
     118                                        if ( 'multi' == add ) { 
     119                                                ui.item.html( ui.item.html().replace(/<[^<>]+>/g, function(m){ return m.replace(/__i__|%i%/g, n); }) ); 
     120                                                ui.item.attr( 'id', id.replace(/__i__|%i%/g, n) ); 
     121                                                n++; 
     122                                                $('div#' + id).find('input.multi_number').val(n); 
     123                                        } else if ( 'single' == add ) { 
     124                                                ui.item.attr( 'id', 'new-' + id ); 
     125                                                rem = 'div#' + id; 
     126                                        } 
     127                                        wpMenus.save( ui.item, 0, 0, 1 ); 
     128                                        ui.item.find('input.add_new').val(''); 
     129                                        ui.item.find('a.menu_item-action').click(); 
     130                                        return; 
     131                                } 
     132                                wpMenus.saveOrder(sb); 
     133                        }, 
     134                        receive: function(e,ui) { 
     135                                if ( !$(this).is(':visible') ) 
     136                                        $(this).sortable('cancel'); 
     137                        } 
     138                }).sortable('option', 'connectWith', 'div.menu_items-sortables').parent().filter('.closed').children('.menu_items-sortables').sortable('disable'); 
     139 
     140                $('#available-menu_items').droppable({ 
     141                        tolerance: 'pointer', 
     142                        accept: function(o){ 
     143                                return $(o).parent().attr('id') != 'menu_item-list'; 
     144                        }, 
     145                        drop: function(e,ui) { 
     146                                ui.draggable.addClass('deleting'); 
     147                                $('#removing-menu_item').hide().children('span').html(''); 
     148                        }, 
     149                        over: function(e,ui) { 
     150                                ui.draggable.addClass('deleting'); 
     151                                $('div.menu_item-placeholder').hide(); 
     152 
     153                                if ( ui.draggable.hasClass('ui-sortable-helper') ) 
     154                                        $('#removing-menu_item').show().children('span') 
     155                                        .html( ui.draggable.find('div.menu_item-title').children('h4').html() ); 
     156                        }, 
     157                        out: function(e,ui) { 
     158                                ui.draggable.removeClass('deleting'); 
     159                                $('div.menu_item-placeholder').show(); 
     160                                $('#removing-menu_item').hide().children('span').html(''); 
     161                        } 
     162                }); 
     163        }, 
     164 
     165        saveOrder : function(sb) { 
     166                if ( sb ) 
     167                        $('#' + sb).closest('div.menu_items-holder-wrap').find('img.ajax-feedback').css('visibility', 'visible'); 
     168 
     169                var a = { 
     170                        action: 'menu_items-order', 
     171                        savemenu_items: $('#_wpnonce_menu_items').val(), 
     172                        menus: [] 
     173                }; 
     174 
     175                $('div.menu_items-sortables').each( function() { 
     176                        a['menus[' + $(this).attr('id') + ']'] = $(this).sortable('toArray').join(','); 
     177                }); 
     178 
     179                $.post( ajaxurl, a, function() { 
     180                        $('img.ajax-feedback').css('visibility', 'hidden'); 
     181                }); 
     182 
     183                this.resize(); 
     184        }, 
     185 
     186        save : function(menu_item, del, animate, order) { 
     187                var sb = menu_item.closest('div.menu_items-sortables').attr('id'), data = menu_item.find('form').serialize(), a; 
     188                menu_item = $(menu_item); 
     189                $('.ajax-feedback', menu_item).css('visibility', 'visible'); 
     190 
     191                a = { 
     192                        action: 'save-menu_item', 
     193                        savemenu_items: $('#_wpnonce_menu_items').val(), 
     194                        menu: sb 
     195                }; 
     196 
     197                if ( del ) 
     198                        a['delete_menu_item'] = 1; 
     199 
     200                data += '&' + $.param(a); 
     201 
     202                $.post( ajaxurl, data, function(r){ 
     203                        var id; 
     204 
     205                        if ( del ) { 
     206                                if ( !$('input.menu_item_number', menu_item).val() ) { 
     207                                        id = $('input.menu_item-id', menu_item).val(); 
     208                                        $('#available-menu_items').find('input.menu_item-id').each(function(){ 
     209                                                if ( $(this).val() == id ) 
     210                                                        $(this).closest('div.menu_item').show(); 
     211                                        }); 
     212                                } 
     213 
     214                                if ( animate ) { 
     215                                        order = 0; 
     216                                        menu_item.slideUp('fast', function(){ 
     217                                                $(this).remove(); 
     218                                                wpMenus.saveOrder(); 
     219                                        }); 
     220                                } else { 
     221                                        menu_item.remove(); 
     222                                        wpMenus.resize(); 
     223                                } 
     224                        } else { 
     225                                $('.ajax-feedback').css('visibility', 'hidden'); 
     226                                if ( r && r.length > 2 ) { 
     227                                        $('div.menu_item-content', menu_item).html(r); 
     228                                        wpMenus.appendTitle(menu_item); 
     229                                        wpMenus.fixLabels(menu_item); 
     230                                } 
     231                        } 
     232                        if ( order ) 
     233                                wpMenus.saveOrder(); 
     234                }); 
     235        }, 
     236 
     237        appendTitle : function(menu_item) { 
     238                var title = $('input[id*="-title"]', menu_item); 
     239                if ( title = title.val() ) { 
     240                        title = title.replace(/<[^<>]+>/g, '').replace(/</g, '&lt;').replace(/>/g, '&gt;'); 
     241                        $(menu_item).children('.menu_item-top').children('.menu_item-title').children() 
     242                                .children('.in-menu_item-title').html(': ' + title); 
     243                } 
     244        }, 
     245 
     246        resize : function() { 
     247                $('div.menu_items-sortables').not('#wp_inactive_menu_items').each(function(){ 
     248                        var h = 50, H = $(this).children('.menu_item').length; 
     249                        h = h + parseInt(H * 48, 10); 
     250                        $(this).css( 'minHeight', h + 'px' ); 
     251                }); 
     252        }, 
     253 
     254    fixWebkit : function(n) { 
     255        n = n ? 'none' : ''; 
     256        $('body').css({ 
     257                        WebkitUserSelect: n, 
     258                        KhtmlUserSelect: n 
     259                }); 
     260    }, 
     261 
     262    fixLabels : function(menu_item) { 
     263                menu_item.children('.menu_item-inside').find('label').each(function(){ 
     264                        var f = $(this).attr('for'); 
     265                        if ( f && f == $('input', this).attr('id') ) 
     266                                $(this).removeAttr('for'); 
     267                }); 
     268        }, 
     269 
     270    close : function(menu_item) { 
     271                menu_item.children('.menu_item-inside').slideUp('fast', function(){ 
     272                        menu_item.css({'width':'','marginLeft':''}); 
     273                }); 
     274        } 
     275}; 
     276 
     277$(document).ready(function($){ wpMenus.init(); }); 
     278 
     279})(jQuery); 
  • wp-admin/menus.php

     
     1<?php 
     2/** 
     3 * Menus administration panel. 
     4 * 
     5 * @package WordPress 
     6 * @subpackage Administration 
     7 */ 
     8 
     9/** WordPress Administration Bootstrap */ 
     10require_once( 'admin.php' ); 
     11 
     12/** WordPress Administration Menus API */ 
     13require_once(ABSPATH . 'wp-admin/includes/menus.php'); 
     14 
     15if ( ! current_user_can('switch_themes') ) 
     16        wp_die( __( 'Cheatin&#8217; uh?' )); 
     17 
     18wp_admin_css( 'menus' ); 
     19 
     20$menus_access = get_user_setting( 'menus_access' ); 
     21if ( isset($_GET['menus-access']) ) { 
     22        $menus_access = 'on' == $_GET['menus-access'] ? 'on' : 'off'; 
     23        set_user_setting( 'menus_access', $menus_access ); 
     24} 
     25 
     26if ( 'on' == $menus_access ) 
     27        add_filter( 'admin_body_class', create_function('', '{return " menus_access ";}') ); 
     28else 
     29        wp_enqueue_script('admin-menus'); 
     30 
     31do_action( 'menu_admin_setup' ); 
     32 
     33$title = __( 'Menus' ); 
     34$parent_file = 'themes.php'; 
     35 
     36// register the inactive_menu_items area as menu 
     37register_menu(array( 
     38        'name' => __('Inactive Menu Items'), 
     39        'id' => 'wp_inactive_menu_items', 
     40        'description' => '', 
     41        'before_menu' => '', 
     42        'after_menu' => '', 
     43)); 
     44 
     45// These are the menu_items grouped by menu 
     46$menu_items_map = wp_get_menu_items(); 
     47if ( empty( $menu_items_map ) ) 
     48        $menu_items_map = wp_get_menu_item_defaults(); 
     49 
     50// look for "lost" menu_items, this has to run at least on each theme change 
     51function retrieve_menu_items() { 
     52        global $wp_registered_menu_item_updates, $wp_registered_menus, $menu_items_map, $wp_registered_menu_items; 
     53 
     54        $_menus_menu_items = array(); 
     55        $menus = array_keys($wp_registered_menus); 
     56 
     57        unset( $menu_items_map['array_version'] ); 
     58 
     59        $old = array_keys($menu_items_map); 
     60        sort($old); 
     61        sort($menus); 
     62 
     63        if ( $old == $menus ) 
     64                return; 
     65 
     66        // Move the known-good ones first 
     67        foreach ( $menus as $id ) { 
     68                if ( array_key_exists( $id, $menu_items_map ) ) { 
     69                        $_menus_menu_items[$id] = $menu_items_map[$id]; 
     70                        unset($menu_items_map[$id], $menus[$id]); 
     71                } 
     72        } 
     73 
     74        // if new theme has less menus than the old theme 
     75        if ( !empty($menu_items_map) ) { 
     76                foreach ( $menu_items_map as $lost => $val ) { 
     77                        if ( is_array($val) ) 
     78                                $_menus_menu_items['wp_inactive_menu_items'] = array_merge( (array) $_menus_menu_items['wp_inactive_menu_items'], $val ); 
     79                } 
     80        } 
     81 
     82        // discard invalid, theme-specific menu_items from menus 
     83        $shown_menu_items = array(); 
     84        foreach ( $_menus_menu_items as $menu => $menu_items ) { 
     85                if ( !is_array($menu_items) ) 
     86                        continue; 
     87 
     88                $_menu_items = array(); 
     89                foreach ( $menu_items as $menu_item ) { 
     90                        if ( isset($wp_registered_menu_items[$menu_item]) ) 
     91                                $_menu_items[] = $menu_item; 
     92                } 
     93                $_menus_menu_items[$menu] = $_menu_items; 
     94                $shown_menu_items = array_merge($shown_menu_items, $_menu_items); 
     95        } 
     96 
     97        $menu_items_map = $_menus_menu_items; 
     98        unset($_menus_menu_items, $_menu_items); 
     99 
     100        // find hidden/lost multi-menu_item instances 
     101        $lost_menu_items = array(); 
     102        foreach ( $wp_registered_menu_items as $key => $val ) { 
     103                if ( in_array($key, $shown_menu_items, true) ) 
     104                        continue; 
     105 
     106                $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key); 
     107 
     108                if ( 2 > (int) $number ) 
     109                        continue; 
     110 
     111                $lost_menu_items[] = $key; 
     112        } 
     113 
     114        $menu_items_map['wp_inactive_menu_items'] = array_merge($lost_menu_items, (array) $menu_items_map['wp_inactive_menu_items']); 
     115        wp_set_menu_items($menu_items_map); 
     116} 
     117retrieve_menu_items(); 
     118 
     119if ( !count($wp_registered_menus) == 1 ) { 
     120        // If only "wp_inactive_menu_items" is defined the theme has no menus, die. 
     121        require_once( 'admin-header.php' ); 
     122?> 
     123 
     124        <div class="wrap"> 
     125        <?php screen_icon(); ?> 
     126        <h2><?php echo esc_html( $title ); ?></h2> 
     127                <div class="error"> 
     128                        <p><?php _e( 'No Menus Defined' ); ?></p> 
     129                </div> 
     130                <p><?php _e( 'The theme you are currently using isn&#8217;t menu-aware, meaning that it has no menus that you are able to change. For information on making your theme menu-aware, please <a href="http://codex.wordpress.org/Custom_Menus_In_Themes">follow these instructions</a>.' ); ?></p> 
     131        </div> 
     132 
     133<?php 
     134        require_once( 'admin-footer.php' ); 
     135        exit; 
     136} 
     137 
     138// We're saving a menu_item without js 
     139if ( isset($_POST['savemenu_item']) || isset($_POST['removemenu_item']) ) { 
     140        $menu_item_id = $_POST['menu_item-id']; 
     141        check_admin_referer("save-delete-menu_item-$menu_item_id"); 
     142 
     143        $number = isset($_POST['multi_number']) ? (int) $_POST['multi_number'] : ''; 
     144        if ( $number ) { 
     145                foreach ( $_POST as $key => $val ) { 
     146                        if ( is_array($val) && preg_match('/__i__|%i%/', key($val)) ) { 
     147                                $_POST[$key] = array( $number => array_shift($val) ); 
     148                                break; 
     149                        } 
     150                } 
     151        } 
     152 
     153        $menu_id = $_POST['menu']; 
     154        $position = isset($_POST[$menu_id . '_position']) ? (int) $_POST[$menu_id . '_position'] - 1 : 0; 
     155 
     156        $id_base = $_POST['id_base']; 
     157        $menu = isset($menu_items_map[$menu_id]) ? $menu_items_map[$menu_id] : array(); 
     158 
     159        // delete 
     160        if ( isset($_POST['removemenu_item']) && $_POST['removemenu_item'] ) { 
     161 
     162                if ( !in_array($menu_item_id, $menu, true) ) { 
     163                        wp_redirect('menu_items.php?error=0'); 
     164                        exit; 
     165                } 
     166 
     167                $menu = array_diff( $menu, array($menu_item_id) ); 
     168                $_POST = array('menu' => $menu_id, 'menu_item-' . $id_base => array(), 'the-menu_item-id' => $menu_item_id, 'delete_menu_item' => '1'); 
     169        } 
     170 
     171        $_POST['menu_item-id'] = $menu; 
     172 
     173        foreach ( (array) $wp_registered_menu_item_updates as $name => $control ) { 
     174                if ( $name != $id_base || !is_callable($control['callback']) ) 
     175                        continue; 
     176 
     177                ob_start(); 
     178                        call_user_func_array( $control['callback'], $control['params'] ); 
     179                ob_end_clean(); 
     180 
     181                break; 
     182        } 
     183 
     184        $menu_items_map[$menu_id] = $menu; 
     185 
     186        // remove old position 
     187        if ( !isset($_POST['delete_menu_item']) ) { 
     188                foreach ( $menu_items_map as $key => $sb ) { 
     189                        if ( is_array($sb) ) 
     190                                $menu_items_map[$key] = array_diff( $sb, array($menu_item_id) ); 
     191                } 
     192                array_splice( $menu_items_map[$menu_id], $position, 0, $menu_item_id ); 
     193        } 
     194 
     195        wp_set_menu_items($menu_items_map); 
     196        wp_redirect('menu_items.php?message=0'); 
     197        exit; 
     198} 
     199 
     200// Output the menu_item form without js 
     201if ( isset($_GET['editmenu_item']) && $_GET['editmenu_item'] ) { 
     202        $menu_item_id = $_GET['editmenu_item']; 
     203 
     204        if ( isset($_GET['addnew']) ) { 
     205                // Default to the first menu 
     206                $menu = array_shift( $keys = array_keys($wp_registered_menus) ); 
     207 
     208                if ( isset($_GET['base']) && isset($_GET['num']) ) { // multi-menu_item 
     209                        // Copy minimal info from an existing instance of this menu_item to a new instance 
     210                        foreach ( $wp_registered_menu_item_controls as $control ) { 
     211                                if ( $_GET['base'] === $control['id_base'] ) { 
     212                                        $control_callback = $control['callback']; 
     213                                        $multi_number = (int) $_GET['num']; 
     214                                        $control['params'][0]['number'] = -1; 
     215                                        $menu_item_id = $control['id'] = $control['id_base'] . '-' . $multi_number; 
     216                                        $wp_registered_menu_item_controls[$control['id']] = $control; 
     217                                        break; 
     218                                } 
     219                        } 
     220                } 
     221        } 
     222 
     223        if ( isset($wp_registered_menu_item_controls[$menu_item_id]) && !isset($control) ) { 
     224                $control = $wp_registered_menu_item_controls[$menu_item_id]; 
     225                $control_callback = $control['callback']; 
     226        } elseif ( !isset($wp_registered_menu_item_controls[$menu_item_id]) && isset($wp_registered_menu_items[$menu_item_id]) ) { 
     227                $name = esc_html( strip_tags($wp_registered_menu_items[$menu_item_id]['name']) ); 
     228        } 
     229 
     230        if ( !isset($name) ) 
     231                $name = esc_html( strip_tags($control['name']) ); 
     232 
     233        if ( !isset($menu) ) 
     234                $menu = isset($_GET['menu']) ? $_GET['menu'] : 'wp_inactive_menu_items'; 
     235 
     236        if ( !isset($multi_number) ) 
     237                $multi_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : ''; 
     238 
     239        $id_base = isset($control['id_base']) ? $control['id_base'] : $control['id']; 
     240 
     241        // show the menu_item form 
     242        $width = ' style="width:' . max($control['width'], 350) . 'px"'; 
     243        $key = isset($_GET['key']) ? (int) $_GET['key'] : 0; 
     244 
     245        require_once( 'admin-header.php' ); ?> 
     246        <div class="wrap"> 
     247        <?php screen_icon(); ?> 
     248        <h2><?php echo esc_html( $title ); ?></h2> 
     249        <div class="editmenu_item"<?php echo $width; ?>> 
     250        <h3><?php printf( __( 'Widget %s' ), $name ); ?></h3> 
     251 
     252        <form action="menu_items.php" method="post"> 
     253        <div class="menu_item-inside"> 
     254<?php 
     255        if ( is_callable( $control_callback ) ) 
     256                call_user_func_array( $control_callback, $control['params'] ); 
     257        else 
     258                echo '<p>' . __('There are no options for this menu_item.') . "</p>\n"; ?> 
     259        </div> 
     260 
     261        <p class="describe"><?php _e('Select both the menu for this menu_item and the position of the menu_item in that menu.'); ?></p> 
     262        <div class="menu_item-position"> 
     263        <table class="widefat"><thead><tr><th><?php _e('menu'); ?></th><th><?php _e('Position'); ?></th></tr></thead><tbody> 
     264<?php 
     265        foreach ( $wp_registered_menus as $sbname => $sbvalue ) { 
     266                echo "\t\t<tr><td><label><input type='radio' name='menu' value='" . esc_attr($sbname) . "'" . checked( $sbname, $menu, false ) . " /> $sbvalue[name]</label></td><td>"; 
     267                if ( 'wp_inactive_menu_items' == $sbname ) { 
     268                        echo '&nbsp;'; 
     269                } else { 
     270                        if ( !isset($menu_items_map[$sbname]) || !is_array($menu_items_map[$sbname]) ) { 
     271                                $j = 1; 
     272                                $menu_items_map[$sbname] = array(); 
     273                        } else { 
     274                                $j = count($menu_items_map[$sbname]); 
     275                                if ( isset($_GET['addnew']) || !in_array($menu_item_id, $menu_items_map[$sbname], true) ) 
     276                                        $j++; 
     277                        } 
     278                        $selected = ''; 
     279                        echo "\t\t<select name='{$sbname}_position'>\n"; 
     280                        echo "\t\t<option value=''>" . __('-- select --') . "</option>\n"; 
     281                        for ( $i = 1; $i <= $j; $i++ ) { 
     282                                if ( in_array($menu_item_id, $menu_items_map[$sbname], true) ) 
     283                                        $selected = selected( $i, $key + 1, false ); 
     284                                echo "\t\t<option value='$i'$selected> $i </option>\n"; 
     285                        } 
     286                        echo "\t\t</select>\n"; 
     287                } 
     288                echo "</td></tr>\n"; 
     289        } ?> 
     290        </tbody></table> 
     291        </div> 
     292 
     293        <div class="menu_item-control-actions"> 
     294<?php   if ( isset($_GET['addnew']) ) { ?> 
     295        <a href="menu_items.php" class="button alignleft"><?php _e('Cancel'); ?></a> 
     296<?php   } else { ?> 
     297        <input type="submit" name="removemenu_item" class="button alignleft" value="<?php esc_attr_e('Delete'); ?>" /> 
     298<?php   } ?> 
     299        <input type="submit" name="savemenu_item" class="button-primary alignright" value="<?php esc_attr_e('Save Widget'); ?>" /> 
     300        <input type="hidden" name="menu_item-id" class="menu_item-id" value="<?php echo esc_attr($menu_item_id); ?>" /> 
     301        <input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" /> 
     302        <input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" /> 
     303<?php   wp_nonce_field("save-delete-menu_item-$menu_item_id"); ?> 
     304        <br class="clear" /> 
     305        </div> 
     306        </form> 
     307        </div> 
     308        </div> 
     309<?php 
     310        require_once( 'admin-footer.php' ); 
     311        exit; 
     312} 
     313 
     314$messages = array( 
     315        __('Changes saved.') 
     316); 
     317 
     318$errors = array( 
     319        __('Error while saving.'), 
     320        __('Error in displaying the menu_item settings form.') 
     321); 
     322 
     323require_once( 'admin-header.php' ); ?> 
     324 
     325<div class="wrap"> 
     326<?php screen_icon(); ?> 
     327<h2><?php echo esc_html( $title ); ?></h2> 
     328 
     329<?php if ( isset($_GET['message']) && isset($messages[$_GET['message']]) ) { ?> 
     330<div id="message" class="updated"><p><?php echo $messages[$_GET['message']]; ?></p></div> 
     331<?php } ?> 
     332<?php if ( isset($_GET['error']) && isset($errors[$_GET['error']]) ) { ?> 
     333<div id="message" class="error"><p><?php echo $errors[$_GET['error']]; ?></p></div> 
     334<?php } ?> 
     335 
     336<div class="menu_item-liquid-left"> 
     337<div id="menu_items-left"> 
     338        <div id="available-menu_items" class="menu_items-holder-wrap"> 
     339                <div class="menu-name"> 
     340                <div class="menu-name-arrow"><br /></div> 
     341                <h3><?php _e('Available Menu Items'); ?> <span id="removing-menu_item"><?php _e('Deactivate'); ?> <span></span></span></h3></div> 
     342                <div class="menu_item-holder"> 
     343                <p class="description"><?php _e('Drag menu items from here to a menu on the right to activate them. Drag menu items back here to deactivate them and delete their settings.'); ?></p> 
     344                <div id="menu_item-list"> 
     345                <?php wp_list_menu_items(); ?> 
     346                </div> 
     347                <br class='clear' /> 
     348                </div> 
     349                <br class="clear" /> 
     350        </div> 
     351 
     352        <div class="menu_items-holder-wrap"> 
     353                <div class="menu-name"> 
     354                <div class="menu-name-arrow"><br /></div> 
     355                <h3><?php _e('Inactive Menu Items'); ?> 
     356                <span><img src="images/wpspin_light.gif" class="ajax-feedback" title="" alt="" /></span></h3></div> 
     357                <div class="menu_item-holder inactive"> 
     358                <p class="description"><?php _e('Drag menu items here to remove them from the menu but keep their settings.'); ?></p> 
     359                <?php wp_list_menu_item_controls('wp_inactive_menu_items'); ?> 
     360                <br class="clear" /> 
     361                </div> 
     362        </div> 
     363</div> 
     364</div> 
     365 
     366<div class="menu_item-liquid-right"> 
     367<div id="menu_items-right"> 
     368<?php 
     369$i = 0; 
     370foreach ( $wp_registered_menus as $menu => $registered_menu ) { 
     371        if ( 'wp_inactive_menu_items' == $menu ) 
     372                continue; 
     373        $closed = $i ? ' closed' : ''; ?> 
     374        <div class="menu_items-holder-wrap<?php echo $closed; ?>"> 
     375        <div class="menu-name"> 
     376        <div class="menu-name-arrow"><br /></div> 
     377        <h3><?php echo esc_html( $registered_menu['name'] ); ?> 
     378        <span><img src="images/wpspin_dark.gif" class="ajax-feedback" title="" alt="" /></span></h3></div> 
     379        <?php wp_list_menu_item_controls( $menu ); // Show the control forms for each of the menu_items in this menu ?> 
     380        </div> 
     381<?php 
     382        $i++; 
     383} ?> 
     384</div> 
     385</div> 
     386<form action="" method="post"> 
     387<?php wp_nonce_field( 'save-menu-items', '_wpnonce_menu_items', false ); ?> 
     388</form> 
     389<br class="clear" /> 
     390</div> 
     391 
     392<?php 
     393do_action( 'menu_admin_page' ); 
     394require_once( 'admin-footer.php' ); 
  • wp-admin/css/menus.dev.css

     
     1html, 
     2body { 
     3        min-width: 950px; 
     4} 
     5 
     6/* 2 column liquid layout */ 
     7div.menu_item-liquid-left { 
     8        float: left; 
     9        clear: left; 
     10        width: 100%; 
     11        margin-right: -325px; 
     12} 
     13 
     14div#menu_items-left { 
     15        margin-left: 5px; 
     16        margin-right: 325px; 
     17} 
     18 
     19div#menu_items-right { 
     20        width: 285px; 
     21        margin: 0 auto; 
     22} 
     23 
     24div.menu_item-liquid-right { 
     25        float: right; 
     26        clear: right; 
     27        width: 300px; 
     28} 
     29 
     30.menu_item-liquid-right .menu_item, 
     31#wp_inactive_menu_items .menu_item, 
     32.menu_item-liquid-right .menu-description { 
     33        width: 250px; 
     34        margin: 0 auto 20px; 
     35        overflow: hidden; 
     36} 
     37 
     38.menu_item-liquid-right .menu-description { 
     39        margin-bottom: 10px; 
     40} 
     41 
     42#wp_inactive_menu_items .menu_item { 
     43        margin: 0 10px 20px; 
     44        float: left; 
     45} 
     46 
     47div.menu-name h3 { 
     48        margin: 0; 
     49        padding: 5px 12px; 
     50        font-size: 13px; 
     51        height: 19px; 
     52        overflow: hidden; 
     53        white-space: nowrap; 
     54} 
     55 
     56div.menu-name { 
     57        background-repeat: repeat-x; 
     58        background-position: 0 0; 
     59        cursor: pointer; 
     60        font-size: 13px; 
     61        border-width: 1px; 
     62        border-style: solid; 
     63        -moz-border-radius-topleft: 8px; 
     64        -moz-border-radius-topright: 8px; 
     65        -webkit-border-top-right-radius: 8px; 
     66        -webkit-border-top-left-radius: 8px; 
     67        -khtml-border-top-right-radius: 8px; 
     68        -khtml-border-top-left-radius: 8px; 
     69        border-top-right-radius: 8px; 
     70        border-top-left-radius: 8px; 
     71} 
     72 
     73.js .closed .menu-name { 
     74        -moz-border-radius-bottomleft: 8px; 
     75        -moz-border-radius-bottomright: 8px; 
     76        -webkit-border-bottom-right-radius: 8px; 
     77        -webkit-border-bottom-left-radius: 8px; 
     78        -khtml-border-bottom-right-radius: 8px; 
     79        -khtml-border-bottom-left-radius: 8px; 
     80        border-bottom-right-radius: 8px; 
     81        border-bottom-left-radius: 8px; 
     82} 
     83 
     84.menu_item-liquid-right .menu_items-sortables, 
     85#menu_items-left .menu_item-holder { 
     86        border-width: 0 1px 1px; 
     87        border-style: none solid solid; 
     88    -moz-border-radius-bottomleft: 8px; 
     89        -moz-border-radius-bottomright: 8px; 
     90        -webkit-border-bottom-right-radius: 8px; 
     91        -webkit-border-bottom-left-radius: 8px; 
     92        -khtml-border-bottom-right-radius: 8px; 
     93        -khtml-border-bottom-left-radius: 8px; 
     94        border-bottom-right-radius: 8px; 
     95        border-bottom-left-radius: 8px; 
     96} 
     97 
     98.js .closed .menu_items-sortables, 
     99.js .closed .menu_item-holder { 
     100        display: none; 
     101} 
     102 
     103.menu_item-liquid-right .menu_items-sortables { 
     104        padding: 15px 0 0; 
     105} 
     106 
     107#available-menu_items .menu_item-holder { 
     108        padding: 7px 5px 0; 
     109} 
     110 
     111#wp_inactive_menu_items { 
     112        padding: 5px 5px 0; 
     113} 
     114 
     115#menu_item-list .menu_item { 
     116        width: 250px; 
     117        margin: 0 10px 15px; 
     118        border: 0 none; 
     119        float: left; 
     120} 
     121 
     122#menu_item-list .menu_item-description { 
     123        padding: 5px 8px; 
     124} 
     125 
     126#menu_item-list .menu_item-top { 
     127        border-width: 1px; 
     128        border-style: solid; 
     129        -moz-border-radius: 6px; 
     130        -khtml-border-radius: 6px; 
     131        -webkit-border-radius: 6px; 
     132        border-radius: 6px; 
     133} 
     134 
     135.menu_item-placeholder { 
     136        border-width: 1px; 
     137        border-style: dashed; 
     138        margin: 0 auto 20px; 
     139        height: 26px; 
     140        width: 250px; 
     141} 
     142 
     143#wp_inactive_menu_items .menu_item-placeholder { 
     144        margin: 0 10px 20px; 
     145        float: left; 
     146} 
     147 
     148div.menu_items-holder-wrap { 
     149        padding: 0; 
     150        margin: 10px 0 20px; 
     151} 
     152 
     153#menu_items-left #available-menu_items { 
     154        background-color: transparent; 
     155        border: 0 none; 
     156} 
     157 
     158ul#menu_item-list { 
     159        list-style: none; 
     160        margin: 0; 
     161        padding: 0; 
     162        min-height: 100px; 
     163} 
     164 
     165.menu_item .menu_item-top { 
     166        font-size: 12px; 
     167        font-weight: bold; 
     168        height: 26px; 
     169        overflow: hidden; 
     170} 
     171 
     172.menu_item-top .menu_item-title { 
     173        padding: 5px 9px; 
     174} 
     175 
     176.menu_item-top .menu_item-title-action { 
     177        float: right; 
     178} 
     179 
     180a.menu_item-action { 
     181        display: block; 
     182        width: 24px; 
     183        height: 26px; 
     184} 
     185 
     186#available-menu_items a.menu_item-action { 
     187        display: none; 
     188} 
     189 
     190.menu_item-top a.menu_item-action { 
     191        background: url("../images/menu-bits.gif") no-repeat scroll 0 -110px; 
     192} 
     193 
     194.menu_item .menu_item-inside, 
     195.menu_item .menu_item-description { 
     196        padding: 12px 12px 10px; 
     197        font-size: 11px; 
     198        line-height: 16px; 
     199} 
     200 
     201.menu_item-inside, 
     202.menu_item-description { 
     203        display: none; 
     204} 
     205 
     206#available-menu_items .menu_item-description { 
     207        display: block; 
     208} 
     209 
     210.menu_item .menu_item-inside p { 
     211        margin: 0 0 1em; 
     212        padding: 0; 
     213} 
     214 
     215.menu_item-title h4 { 
     216        margin: 0; 
     217        line-height: 1.3; 
     218        overflow: hidden; 
     219        white-space: nowrap; 
     220} 
     221 
     222.menu_items-sortables { 
     223        min-height: 90px; 
     224} 
     225 
     226.menu_item-control-actions { 
     227        margin-top: 8px; 
     228} 
     229 
     230.menu_item-control-actions a { 
     231        text-decoration: none; 
     232} 
     233 
     234.menu_item-control-actions a:hover { 
     235        text-decoration: underline; 
     236} 
     237 
     238.menu_item-control-actions .ajax-feedback { 
     239        padding-bottom: 3px; 
     240} 
     241 
     242.menu_item-control-actions div.alignleft { 
     243        margin-top: 6px; 
     244} 
     245 
     246div#menu-info { 
     247        padding: 0 1em; 
     248        margin-bottom: 1em; 
     249        font-size: 11px; 
     250} 
     251 
     252.menu_item-title a, 
     253.menu_item-title a:hover { 
     254        text-decoration: none; 
     255        border-bottom: none; 
     256} 
     257 
     258.menu_item-control-edit { 
     259        display: block; 
     260        font-size: 11px; 
     261        font-weight: normal; 
     262        line-height: 26px; 
     263        padding: 0 8px 0 0; 
     264} 
     265 
     266a.menu_item-control-edit { 
     267        text-decoration: none; 
     268} 
     269 
     270.menu_item-control-edit .add, 
     271.menu_item-control-edit .edit { 
     272        display: none; 
     273} 
     274 
     275#available-menu_items .menu_item-control-edit .add, 
     276#menu_items-right .menu_item-control-edit .edit, 
     277#wp_inactive_menu_items .menu_item-control-edit .edit { 
     278        display: inline; 
     279} 
     280 
     281.editmenu_item { 
     282        margin: 0 auto 15px; 
     283} 
     284 
     285.editmenu_item .menu_item-inside { 
     286        display: block; 
     287        border-width: 1px; 
     288        border-style: solid; 
     289        padding: 10px; 
     290        -moz-border-radius: 6px; 
     291        -khtml-border-radius: 6px; 
     292        -webkit-border-radius: 6px; 
     293        border-radius: 6px; 
     294} 
     295 
     296.inactive p.description { 
     297        margin: 5px 15px 8px; 
     298} 
     299 
     300#available-menu_items p.description { 
     301        margin: 0 12px 12px; 
     302} 
     303 
     304.menu_item-position { 
     305        margin-top: 8px; 
     306} 
     307 
     308.inactive { 
     309        padding-top: 2px; 
     310} 
     311 
     312.menu-name-arrow { 
     313        float: right; 
     314        height: 29px; 
     315        width: 26px; 
     316} 
     317 
     318.menu_item-title .in-menu_item-title { 
     319        font-size: 11px; 
     320        white-space: nowrap; 
     321} 
     322 
     323#removing-menu_item { 
     324        display: none; 
     325        font-weight: normal; 
     326        padding-left: 15px; 
     327        font-size: 12px; 
     328} 
     329 
     330.menu_item-control-noform, 
     331#access-off, 
     332.menu_items_access .menu_item-action, 
     333.menu_items_access .menu-name-arrow, 
     334.menu_items_access #access-on, 
     335.menu_items_access .menu_item-holder .description { 
     336        display: none; 
     337} 
     338 
     339.menu_items_access .menu_item-holder, 
     340.menu_items_access #menu_item-list { 
     341        padding-top: 10px; 
     342} 
     343 
     344.menu_items_access #access-off { 
     345        display: inline; 
     346} 
     347 
     348.menu_items_access #wpbody-content .menu_item-title-action, 
     349.menu_items_access #wpbody-content .menu_item-control-edit, 
     350.menu_items_access .closed .menu_items-sortables, 
     351.menu_items_access .closed .menu_item-holder { 
     352        display: block; 
     353} 
     354 
     355.menu_items_access .closed .menu-name { 
     356        -moz-border-radius-bottomleft: 0; 
     357        -moz-border-radius-bottomright: 0; 
     358        -webkit-border-bottom-right-radius: 0; 
     359        -webkit-border-bottom-left-radius: 0; 
     360        -khtml-border-bottom-right-radius: 0; 
     361        -khtml-border-bottom-left-radius: 0; 
     362        border-bottom-right-radius: 0; 
     363        border-bottom-left-radius: 0; 
     364} 
     365 
     366.menu_items_access .menu-name, 
     367.menu_items_access .menu_item .menu_item-top { 
     368        cursor: default; 
     369} 
     370 
  • wp-admin/css/colors-fresh.dev.css

     
    33} 
    44 
    55* html input, 
    6 * html .widget { 
     6* html .widget,  
     7* html .menu_item { 
    78        border-color: #dfdfdf; 
    89} 
    910 
     
    131132} 
    132133 
    133134.widget .widget-top, 
     135.menu_item .menu_item-top, 
    134136.postbox h3, 
    135137.stuffbox h3 { 
    136138        background: #dfdfdf url("../images/gray-grad.png") repeat-x left top; 
     
    644646} 
    645647 
    646648.widget, 
    647 #widget-list .widget-top, 
     649.menu_item, 
     650#widget-list .widget-top,  
     651#menu_item-list .menu_item-top, 
    648652.postbox, 
    649653#titlediv, 
    650654#poststuff .postarea, 
     
    652656        border-color: #dfdfdf; 
    653657} 
    654658 
    655 .widget, 
     659.widget,  
     660.menu_item, 
    656661.postbox { 
    657662        background-color: #fff; 
    658663} 
     
    661666        color: #464646; 
    662667} 
    663668 
    664 .widget .widget-top, 
     669#widget-list .widget-top,  
     670#menu_item-list .menu_item-top, 
    665671.ui-sortable .postbox h3:hover { 
    666672        color: #000; 
    667673} 
     
    741747.file-error, 
    742748abbr.required, 
    743749.widget-control-remove:hover, 
     750.menu_item-control-remove:hover, 
    744751table.widefat .delete a:hover, 
    745752table.widefat .trash a:hover, 
    746753table.widefat .spam a:hover, 
     
    10141021#editorcontainer, 
    10151022#post-status-info, 
    10161023#titlediv #title, 
    1017 .editwidget .widget-inside { 
     1024.editwidget .widget-inside, 
     1025.editmenu_item .menu_item-inside { 
    10181026        border-color: #dfdfdf; 
    10191027} 
    10201028 
     
    16161624} 
    16171625 
    16181626div.widgets-sortables, 
    1619 #widgets-left .inactive { 
     1627div.menu_items-sortables, 
     1628#widgets-left .inactive, 
     1629#menu_items-left .inactive { 
    16201630        background-color: #f1f1f1; 
    16211631        border-color: #ddd; 
    16221632} 
    16231633 
    1624 #available-widgets .widget-holder { 
     1634#available-widgets .widget-holder, 
     1635#available-menu_items .menu_item-holder { 
    16251636        background-color: #fff; 
    16261637        border-color: #ddd; 
    16271638} 
    16281639 
    1629 #widgets-left .sidebar-name { 
     1640#widgets-left .sidebar-name,  
     1641#menu_items-left .menu-name { 
    16301642        background-color: #aaa; 
    16311643        background-image: url(../images/ed-bg.gif); 
    16321644        text-shadow: #fff 0 1px 0; 
    16331645        border-color: #dfdfdf; 
    16341646} 
    16351647 
    1636 #widgets-right .sidebar-name { 
     1648#widgets-right .sidebar-name, 
     1649#menu_items-right .menu-name { 
    16371650        background-image: url(../images/fav.png); 
    16381651        text-shadow: #3f3f3f 0 -1px 0; 
    16391652        background-color: #636363; 
     
    16421655} 
    16431656 
    16441657.sidebar-name:hover, 
    1645 #removing-widget { 
     1658.menu-name:hover, 
     1659#removing-widget, 
     1660#removing-menu_item { 
    16461661        color: #d54e21; 
    16471662} 
    16481663 
    1649 #removing-widget span { 
     1664#removing-widget span, 
     1665#removing-menu_item span { 
    16501666        color: black; 
    16511667} 
    16521668 
    1653 #widgets-left .sidebar-name-arrow { 
     1669#widgets-left .sidebar-name-arrow, 
     1670#menu_items-left .menu-name-arrow { 
    16541671        background: transparent url(../images/menu-bits.gif) no-repeat scroll left -109px; 
    16551672} 
    16561673 
    1657 #widgets-right .sidebar-name-arrow { 
     1674#widgets-right .sidebar-name-arrow, 
     1675#menu_items-right .menu-name-arrow { 
    16581676        background: transparent url(../images/fav-arrow.gif) no-repeat scroll 0 -1px; 
    16591677} 
    16601678 
    1661 .in-widget-title { 
     1679.in-widget-title, 
     1680.in-menu_item-title { 
    16621681        color: #606060; 
    16631682} 
    16641683 
    1665 .deleting .widget-title * { 
     1684.deleting .widget-title *, 
     1685.deleting .menu_item-title * { 
    16661686        color: #aaa; 
    16671687} 
    16681688 
  • wp-admin/css/menus-rtl.css

     
     1 
     2ul#menu_item-list li.menu_item-list-item div.menu_item-description { 
     3        margin: 0 200px 0 0; 
     4        padding: 0 4em 0 0; 
     5} 
     6.menu_item-control-save, 
     7.menu_item-control-remove { 
     8        margin-right: 0; 
     9        margin-left: 8px; 
     10        float: right; 
     11}