diff options
-rw-r--r-- | wp-admin/css/colors-fresh.css | 24 | ||||
-rw-r--r-- | wp-admin/css/wp-admin-rtl.css | 41 | ||||
-rw-r--r-- | wp-admin/css/wp-admin.css | 182 | ||||
-rw-r--r-- | wp-admin/includes/nav-menu.php | 169 | ||||
-rw-r--r-- | wp-admin/js/nav-menu.js | 356 | ||||
-rw-r--r-- | wp-admin/nav-menus.php | 433 |
6 files changed, 729 insertions, 476 deletions
diff --git a/wp-admin/css/colors-fresh.css b/wp-admin/css/colors-fresh.css index f8702d1528..febb39f530 100644 --- a/wp-admin/css/colors-fresh.css +++ b/wp-admin/css/colors-fresh.css @@ -400,7 +400,8 @@ div.dashboard-widget-submit input:hover, .submitbox .submitdelete:hover, #media-items a.delete:hover, -#media-items a.delete-permanently:hover { +#media-items a.delete-permanently:hover, +#nav-menu-footer .menu-delete:hover { color: #fff; background-color: #f00; border-bottom-color: #f00; @@ -1682,6 +1683,27 @@ div.widgets-sortables, background: #21759b; color: #fff; } + +.manage-menus { + border: 1px solid #eeeeee; + background: #fbfbfb; +} + +.menu-settings { + border-top: 1px solid #eeeeee; +} + +.theme-location-set { + color: #999999; +} + +.nav-menus-php .delete-action a { + color: #bc0b0b; +} + +.is-submenu { + color: #999999; +} /* end added from nav-menu.css */ .nav-tab { diff --git a/wp-admin/css/wp-admin-rtl.css b/wp-admin/css/wp-admin-rtl.css index 5d120e526f..78ba55381d 100644 --- a/wp-admin/css/wp-admin-rtl.css +++ b/wp-admin/css/wp-admin-rtl.css @@ -44,6 +44,8 @@ TABLE OF CONTENTS: 25.0 - TinyMCE tweaks 26.0 - Full Overlay w/ Sidebar 27.0 - Customize Loader +28.0 - Nav Menus +29.0 - HiDPI ------------------------------------------------------------------------------*/ @@ -2303,10 +2305,6 @@ body.login { margin-right:0; } -.auto-add-pages { - float: right; -} - /* Star ratings */ div.star-holder { background: url('../images/stars-rtl.png?ver=20121108') repeat-x bottom right; @@ -2543,9 +2541,38 @@ div.sidebar-name h3 { left: 20px; } -/** - * HiDPI Displays - */ +/*------------------------------------------------------------------------------ + 28.0 - Nav Menus +------------------------------------------------------------------------------*/ +.nav-menus-php .major-publishing-actions .publishing-action { + float: left; +} + +.menu-settings dd { + float: right; + padding-right: 170px; +} + +.manage-menus span { + float: right; +} + +.menu-settings dt { + left: auto; + right: 0; +} + +.menu-settings dd input, +.menu-settings dd span, +.menu-settings dd label, +.manage-menus select { + float: right; + margin-right: 6px; +} + +/*------------------------------------------------------------------------------ + 29.0 - HiDPI +------------------------------------------------------------------------------*/ @media print, (-o-min-device-pixel-ratio: 5/4), (-webkit-min-device-pixel-ratio: 1.25), diff --git a/wp-admin/css/wp-admin.css b/wp-admin/css/wp-admin.css index 55aa296fda..c22c5915ef 100644 --- a/wp-admin/css/wp-admin.css +++ b/wp-admin/css/wp-admin.css @@ -6704,8 +6704,17 @@ a.rsswidget { /* nav-menu */ +.nav-menus-php #message { + display: none; +} + +.no-js #message { + display: block; +} + #nav-menus-frame { margin-left: 300px; + margin-top: 28px; } #wpbody-content #menu-settings-column { @@ -6714,11 +6723,7 @@ a.rsswidget { margin-left: -300px; clear: both; float: left; - padding-top: 24px; -} - -.no-js #wpbody-content #menu-settings-column { - padding-top: 31px; + padding-top: 0; } #menu-settings-column .inside { @@ -6739,10 +6744,89 @@ a.rsswidget { position: relative; } +.blank-slate .menu-name { + height: 2em; +} + +.blank-slate .menu-settings { + border: none; + margin-top: 0; + padding-top: 0; + overflow: hidden; +} + +.is-submenu { + font-style: italic; + font-weight: normal; + margin-left: 4px; +} + +.manage-menus { + margin-top: 13px; + padding: 10px; + overflow: hidden; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.manage-menus select { + float: left; + margin-right: 6px; +} + +.manage-menus .selected-menu { + float: left; + margin: 5px 6px 0 0; +} + +.manage-menus .submit-btn { + float: left; + margin-top: 1px; +} + +.menu-edit p { + margin: .3em 0 .6em; +} + +.menu-settings { + margin-top: 2em; + padding-top: 16px; + overflow: hidden; +} + +.menu-settings dl { + margin: 0 0 10px; + overflow: hidden; + position: relative; +} + +.menu-settings dd { + float: left; + margin: 0; + width: 60%; + padding-left: 170px; +} + +.menu-settings dt { + clear: both; + left: 0; + padding: 3px 0 0; + position: absolute; +} + +.menu-edit .checkbox-input { + margin-top: 4px; +} + +.theme-location-set { + font-size: 11px; +} + /* Menu Container */ #menu-management-liquid { float: left; min-width: 100%; + margin-top: 3px; } #menu-management { @@ -6757,7 +6841,7 @@ a.rsswidget { } .nav-menus-php #post-body { - padding: 10px; + padding: 0 10px; border-width: 1px 0; border-style: solid; } @@ -6769,6 +6853,11 @@ a.rsswidget { #nav-menu-header { border-bottom: 1px solid; + margin-bottom: 13px; +} + +#nav-menu-header .menu-name-label { + margin-top: 2px; } #nav-menu-footer { @@ -6789,54 +6878,6 @@ a.rsswidget { font-weight:bold; } -/* Menu Tabs */ - -#menu-management .nav-tabs-nav { - margin: 0 20px; -} - -#menu-management .nav-tabs-arrow { - width: 10px; - padding: 0 5px 4px; - cursor: pointer; - position: absolute; - top: 0; - line-height: 22px; - font-size: 18px; -} - -#menu-management .nav-tabs-arrow-left { - left: 0; -} - -#menu-management .nav-tabs-arrow-right { - right: 0; - text-align: right; -} - -#menu-management .nav-tabs-wrapper { - width: 100%; - height: 28px; - margin-bottom: -1px; - overflow: hidden; -} - -#menu-management .nav-tabs { - padding-left: 20px; - padding-right: 10px; -} - -.js #menu-management .nav-tabs { - float: left; - margin-left: 0px; - margin-right: -400px; -} - -#menu-management .nav-tab { - margin-bottom: 0; - font-size: 14px; -} - #select-nav-menu-container { text-align: right; padding: 0 10px 3px 10px; @@ -7033,7 +7074,8 @@ a.rsswidget { } #menu-to-edit { - padding: 1em 0; + margin: 0; + padding: 0.1em 0; } .menu ul { @@ -7049,7 +7091,7 @@ a.rsswidget { clear:both; line-height:1.5em; position:relative; - margin: 13px 0 0 0; + margin: 9px 0 0; } .menu-item-handle { @@ -7269,34 +7311,16 @@ body.menu-max-depth-11 { min-width: 1280px !important; } text-align: right; float: right; line-height: 23px; - margin: 5px 0 1px; + margin: 2px 0 1px; } -.nav-menus-php .major-publishing-actions .delete-action { - vertical-align: middle; - text-align: left; - float: left; - padding-right: 15px; - margin-top: 5px; -} - -.menu-name-label span, -.auto-add-pages label { - font-size: 12px; - font-style: normal; -} - -.menu-name-label { - margin-right: 15px; -} - -.auto-add-pages input { - margin-top: 0; +.nav-menus-php .blank-slate .menu-settings { + display: none; } -.auto-add-pages { - margin-top: 4px; +.nav-menus-php .delete-action { float: left; + margin-top: 2px; } .nav-menus-php .submitbox .submitcancel { diff --git a/wp-admin/includes/nav-menu.php b/wp-admin/includes/nav-menu.php index 60644628d9..c28ea891cf 100644 --- a/wp-admin/includes/nav-menu.php +++ b/wp-admin/includes/nav-menu.php @@ -81,11 +81,15 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu { $title = empty( $item->label ) ? $title : $item->label; + $submenu_text = ''; + if ( 0 == $depth ) + $submenu_text = 'style="display: none;"'; + ?> <li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode(' ', $classes ); ?>"> <dl class="menu-item-bar"> <dt class="menu-item-handle"> - <span class="item-title"><?php echo esc_html( $title ); ?></span> + <span class="item-title"><?php echo esc_html( $title ); ?> <span class="is-submenu" <?php echo $submenu_text; ?>><?php _e( 'sub item' ); ?></span></span> <span class="item-controls"> <span class="item-type"><?php echo esc_html( $item->type_label ); ?></span> <span class="item-order hide-if-js"> @@ -182,10 +186,10 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu { 'action' => 'delete-menu-item', 'menu-item' => $item_id, ), - remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) ) + admin_url( 'nav-menus.php' ) ), 'delete-menu_item_' . $item_id - ); ?>"><?php _e('Remove'); ?></a> <span class="meta-sep"> | </span> <a class="item-cancel submitcancel" id="cancel-<?php echo $item_id; ?>" href="<?php echo esc_url( add_query_arg( array('edit-menu-item' => $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) ) ); + ); ?>"><?php _e( 'Remove' ); ?></a> <span class="meta-sep hide-if-no-js"> | </span> <a class="item-cancel submitcancel hide-if-no-js" id="cancel-<?php echo $item_id; ?>" href="<?php echo esc_url( add_query_arg( array( 'edit-menu-item' => $item_id, 'cancel' => time() ), admin_url( 'nav-menus.php' ) ) ); ?>#menu-item-settings-<?php echo $item_id; ?>"><?php _e('Cancel'); ?></a> </div> @@ -382,10 +386,8 @@ function _wp_ajax_menu_quick_search( $request = array() ) { **/ function wp_nav_menu_setup() { // Register meta boxes - if ( wp_get_nav_menus() ) - add_meta_box( 'nav-menu-theme-locations', __( 'Theme Locations' ), 'wp_nav_menu_locations_meta_box' , 'nav-menus', 'side', 'default' ); - add_meta_box( 'add-custom-links', __('Custom Links'), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' ); wp_nav_menu_post_type_meta_boxes(); + add_meta_box( 'add-custom-links', __( 'Add Links' ), 'wp_nav_menu_item_link_meta_box', 'nav-menus', 'side', 'default' ); wp_nav_menu_taxonomy_meta_boxes(); // Register advanced menu items (columns) @@ -411,7 +413,7 @@ function wp_initial_nav_menu_meta_boxes() { if ( get_user_option( 'metaboxhidden_nav-menus' ) !== false || ! is_array($wp_meta_boxes) ) return; - $initial_meta_boxes = array( 'nav-menu-theme-locations', 'add-custom-links', 'add-page', 'add-category' ); + $initial_meta_boxes = array( 'nav-menu-theme-locations', 'add-page', 'add-custom-links', 'add-category' ); $hidden_meta_boxes = array(); foreach ( array_keys($wp_meta_boxes['nav-menus']) as $context ) { @@ -489,7 +491,7 @@ function wp_nav_menu_locations_meta_box() { $menu_locations = get_nav_menu_locations(); $num_locations = count( array_keys($locations) ); - echo '<p class="howto">' . sprintf( _n('Your theme supports %s menu. Select which menu you would like to use.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n($num_locations) ) . '</p>'; + echo '<p class="howto">' . _n( 'Select a menu to use within your theme.', 'Select the menus you will use in your theme.', $num_locations ) . '</p>'; foreach ( $locations as $location => $description ) { ?> @@ -512,13 +514,33 @@ function wp_nav_menu_locations_meta_box() { } ?> <p class="button-controls"> - <?php submit_button( __( 'Save' ), 'primary right', 'nav-menu-locations', false, disabled( $nav_menu_selected_id, 0, false ) ); ?> + <?php submit_button( __( 'Save' ), 'primary right', 'nav-menu-locations', false, wp_nav_menu_disabled_check( $nav_menu_selected_id ) ); ?> <span class="spinner"></span> </p> <?php } /** + * Check whether to disable the Menu Locations meta box submit button + * + * @since 3.6.0 + * + * @uses global $one_theme_location_no_menus to determine if no menus exist + * @uses disabled() to output the disabled attribute in $other_attributes param in submit_button() + * + * @param int|string $nav_menu_selected_id (id, name or slug) of the currently-selected menu + * @return string Disabled attribute if at least one menu exists, false if not +*/ +function wp_nav_menu_disabled_check( $nav_menu_selected_id ) { + global $one_theme_location_no_menus; + + if ( $one_theme_location_no_menus ) + return false; + + return disabled( $nav_menu_selected_id, 0 ); +} + +/** * Displays a metabox for the custom links menu item. * * @since 3.0.0 @@ -554,14 +576,14 @@ function wp_nav_menu_item_link_meta_box() { <p id="menu-item-name-wrap"> <label class="howto" for="custom-menu-item-name"> - <span><?php _e('Label'); ?></span> + <span><?php _e( 'Link Text' ); ?></span> <input id="custom-menu-item-name" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e('Menu Item'); ?>" /> </label> </p> <p class="button-controls"> <span class="add-to-menu"> - <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" id="submit-customlinkdiv" /> + <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" id="submit-customlinkdiv" /> <span class="spinner"></span> </span> </p> @@ -768,18 +790,18 @@ function wp_nav_menu_item_post_type_meta_box( $object, $post_type ) { <p class="button-controls"> <span class="list-controls"> <a href="<?php - echo esc_url(add_query_arg( + echo esc_url( add_query_arg( array( $post_type_name . '-tab' => 'all', 'selectall' => 1, ), - remove_query_arg($removed_args) + remove_query_arg( $removed_args ) )); ?>#posttype-<?php echo $post_type_name; ?>" class="select-all"><?php _e('Select All'); ?></a> </span> <span class="add-to-menu"> - <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-post-type-menu-item" id="submit-posttype-<?php echo $post_type_name; ?>" /> + <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( __( 'Add to Menu' ) ); ?>" name="add-post-type-menu-item" id="<?php esc_attr_e( 'submit-posttype-' . $post_type_name ); ?>" /> <span class="spinner"></span> </span> </p> @@ -955,7 +977,7 @@ function wp_nav_menu_item_taxonomy_meta_box( $object, $taxonomy ) { </span> <span class="add-to-menu"> - <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-taxonomy-menu-item" id="submit-taxonomy-<?php echo $taxonomy_name; ?>" /> + <input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( __( 'Add to Menu' ) ); ?>" name="add-taxonomy-menu-item" id="<?php esc_attr_e( 'submit-taxonomy-' . $taxonomy_name ); ?>" /> <span class="spinner"></span> </span> </p> @@ -1086,7 +1108,7 @@ function wp_get_nav_menu_to_edit( $menu_id = 0 ) { $menu_items = wp_get_nav_menu_items( $menu->term_id, array('post_status' => 'any') ); $result = '<div id="menu-instructions" class="post-body-plain'; $result .= ( ! empty($menu_items) ) ? ' menu-instructions-inactive">' : '">'; - $result .= '<p>' . __('Select menu items (pages, categories, links) from the boxes at left to begin building your custom menu.') . '</p>'; + $result .= '<p>' . __( 'Next, add menu items (i.e. pages, links, categories) from the column on the left.' ) . '</p>'; $result .= '</div>'; if( empty($menu_items) ) @@ -1158,5 +1180,118 @@ function _wp_delete_orphaned_draft_menu_items() { foreach( (array) $menu_items_to_delete as $menu_item_id ) wp_delete_post( $menu_item_id, true ); } - add_action('admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items'); + +/** + * Delete nav menus from the nav menu management screen + * + * @since 3.6.0 + * @access private + * + * @param int|string $nav_menu_id The menu to delete (id, slug, or name) + * @return false if Error, otherwise true + */ +function _wp_delete_nav_menu( $nav_menu_id ) { + + if ( ! is_nav_menu( $nav_menu_id ) ) + return; + + $deleted_nav_menu = wp_get_nav_menu_object( $nav_menu_id ); + $delete_nav_menu = wp_delete_nav_menu( $nav_menu_id ); + + if ( is_wp_error( $delete_nav_menu ) ) + return $delete_nav_menu; + + // Remove this menu from any locations. + $locations = get_theme_mod( 'nav_menu_locations' ); + foreach ( (array) $locations as $location => $menu_id ) { + if ( $menu_id == $nav_menu_id ) + $locations[ $location ] = 0; + } + set_theme_mod( 'nav_menu_locations', $locations ); + return true; +} + +/** + * Saves nav menu items + * + * @since 3.6.0 + * + * @uses wp_get_nav_menu_items() to retrieve the nav menu's menu items + * @uses wp_defer_term_counter() to enable then disable term counting + * + * @param int|string $nav_menu_selected_id (id, slug, or name ) of the currently-selected menu + * @param string $nav_menu_selected_title Title of the currently-selected menu + * @return array $messages The menu updated message + */ +function wp_nav_menu_update_menu_items ( $nav_menu_selected_id, $nav_menu_selected_title ) { + $unsorted_menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array( 'orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID', 'post_status' => 'draft,publish' ) ); + + $menu_items = array(); + // Index menu items by db ID + foreach ( $unsorted_menu_items as $_item ) + $menu_items[$_item->db_id] = $_item; + + $post_fields = array( + 'menu-item-db-id', 'menu-item-object-id', 'menu-item-object', + 'menu-item-parent-id', 'menu-item-position', 'menu-item-type', + 'menu-item-title', 'menu-item-url', 'menu-item-description', + 'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn' + ); + + wp_defer_term_counting( true ); + // Loop through all the menu items' POST variables + if ( ! empty( $_POST['menu-item-db-id'] ) ) { + foreach( (array) $_POST['menu-item-db-id'] as $_key => $k ) { + + // Menu item title can't be blank + if ( empty( $_POST['menu-item-title'][$_key] ) ) + continue; + + $args = array(); + foreach ( $post_fields as $field ) + $args[$field] = isset( $_POST[$field][$_key] ) ? $_POST[$field][$_key] : ''; + + $menu_item_db_id = wp_update_nav_menu_item( $nav_menu_selected_id, ( $_POST['menu-item-db-id'][$_key] != $_key ? 0 : $_key ), $args ); + + if ( is_wp_error( $menu_item_db_id ) ) + $messages[] = '<div id="message" class="error"><p>' . $menu_item_db_id->get_error_message() . '</p></div>'; + elseif ( isset( $menu_items[$menu_item_db_id] ) ) + unset( $menu_items[$menu_item_db_id] ); + } + } + + // Remove menu items from the menu that weren't in $_POST + if ( ! empty( $menu_items ) ) { + foreach ( array_keys( $menu_items ) as $menu_item_id ) { + if ( is_nav_menu_item( $menu_item_id ) ) { + wp_delete_post( $menu_item_id ); + } + } + } + + // Store 'auto-add' pages. + $auto_add = ! empty( $_POST['auto-add-pages'] ); + $nav_menu_option = (array) get_option( 'nav_menu_options' ); + if ( ! isset( $nav_menu_option['auto_add'] ) ) + $nav_menu_option['auto_add'] = array(); + if ( $auto_add ) { + if ( ! in_array( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) ) + $nav_menu_option['auto_add'][] = $nav_menu_selected_id; + } else { + if ( false !== ( $key = array_search( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) ) ) + unset( $nav_menu_option['auto_add'][$key] ); + } + // Remove nonexistent/deleted menus + $nav_menu_option['auto_add'] = array_intersect( $nav_menu_option['auto_add'], wp_get_nav_menus( array( 'fields' => 'ids' ) ) ); + update_option( 'nav_menu_options', $nav_menu_option ); + + wp_defer_term_counting( false ); + + do_action( 'wp_update_nav_menu', $nav_menu_selected_id ); + + $messages[] = '<div id="message" class="updated"><p>' . sprintf( __( '<strong>%1$s</strong> has been updated.' ), $nav_menu_selected_title ) . '</p></div>'; + unset( $menu_items, $unsorted_menu_items ); + + return $messages; +} diff --git a/wp-admin/js/nav-menu.js b/wp-admin/js/nav-menu.js index 20f0fc3bec..5380c98e3d 100644 --- a/wp-admin/js/nav-menu.js +++ b/wp-admin/js/nav-menu.js @@ -45,9 +45,14 @@ var wpNavMenu; if( api.menuList.length ) // If no menu, we're in the + tab. this.initSortables(); - this.initToggles(); + if( oneThemeLocationNoMenus ) + $( '#posttype-page' ).addSelectedToMenu( api.addMenuItemToBottom ); + + this.messageFadeIn(); - this.initTabManager(); + this.initAccessibility(); + + this.initToggles(); }, jQueryExtensions : function() { @@ -84,19 +89,55 @@ var wpNavMenu; }); return result; }, + shiftHorizontally : function( dir ) { + return this.each(function(){ + var t = $(this), + depth = t.menuItemDepth(), + newDepth = depth + dir; + + // Change .menu-item-depth-n class + t.moveHorizontally( newDepth, depth ); + }); + }, + moveHorizontally : function( newDepth, depth ) { + return this.each(function(){ + var t = $(this), + children = t.childMenuItems(), + diff = newDepth - depth, + subItemText = t.find('.is-submenu'); + + // Change .menu-item-depth-n class + t.updateDepthClass( newDepth, depth ).updateParentMenuItemDBId(); + + // If it has children, move those too + if ( children ) { + children.each(function( index ) { + var t = $(this), + thisDepth = t.menuItemDepth(), + newDepth = thisDepth + diff; + t.updateDepthClass(newDepth, thisDepth).updateParentMenuItemDBId(); + }); + } + + // Show "Sub item" helper text + if (0 === newDepth) + subItemText.hide(); + else + subItemText.show(); + }); + }, updateParentMenuItemDBId : function() { return this.each(function(){ var item = $(this), - input = item.find('.menu-item-data-parent-id'), - depth = item.menuItemDepth(), - parent = item.prev(); + input = item.find( '.menu-item-data-parent-id' ), + depth = parseInt( item.menuItemDepth() ), + parentDepth = depth - 1, + parent = item.prevAll( '.menu-item-depth-' + parentDepth ).first(); - if( depth == 0 ) { // Item is on the top level, has no parent + if ( 0 == depth ) { // Item is on the top level, has no parent input.val(0); } else { // Find the parent item, and retrieve its object id. - while( ! parent[0] || ! parent[0].className || -1 == parent[0].className.indexOf('menu-item') || ( parent.menuItemDepth() != depth - 1 ) ) - parent = parent.prev(); - input.val( parent.find('.menu-item-data-db-id').val() ); + input.val( parent.find( '.menu-item-data-db-id' ).val() ); } }); }, @@ -120,7 +161,7 @@ var wpNavMenu; return this.each(function() { var t = $(this), menuItems = {}, - checkboxes = t.find('.tabs-panel-active .categorychecklist li input:checked'), + checkboxes = ( oneThemeLocationNoMenus && 0 == t.find('.tabs-panel-active .categorychecklist li input:checked').length ) ? t.find('#page-all li input[type="checkbox"]') : t.find('.tabs-panel-active .categorychecklist li input:checked'), re = new RegExp('menu-item\\[(\[^\\]\]*)'); processMethod = processMethod || api.addMenuItemToBottom; @@ -223,6 +264,128 @@ var wpNavMenu; }); }, + initAccessibility : function() { + $( '.item-edit' ).off( 'focus' ).on( 'focus', function(){ + $(this).on( 'keydown', function(e){ + + var $this = $(this); + + // Bail if it's not an arrow key + if ( 37 != e.which && 38 != e.which && 39 != e.which && 40 != e.which ) + return; + + // Avoid multiple keydown events + $this.off('keydown'); + + var menuItems = $('#menu-to-edit li'); + menuItemsCount = menuItems.length, + thisItem = $this.parents( 'li.menu-item' ), + thisItemChildren = thisItem.childMenuItems(), + thisItemData = thisItem.getItemData(), + thisItemDepth = parseInt( thisItem.menuItemDepth() ), + thisItemPosition = parseInt( thisItem.index() ), + nextItem = thisItem.next(), + nextItemChildren = nextItem.childMenuItems(), + nextItemDepth = parseInt( nextItem.menuItemDepth() ) + 1, + prevItem = thisItem.prev(), + prevItemDepth = parseInt( prevItem.menuItemDepth() ), + prevItemId = prevItem.getItemData()['menu-item-db-id']; + + // Bail if there is only one menu item + if ( 1 === menuItemsCount ) + return; + + // If RTL, swap left/right arrows + var arrows = { '38' : 'up', '40' : 'down', '37' : 'left', '39' : 'right' }; + if ( $('body').hasClass('rtl') ) + arrows = { '38' : 'up', '40' : 'down', '39' : 'left', '37' : 'right' }; + + switch ( arrows[e.which] ) { + case 'up': + var newItemPosition = thisItemPosition - 1; + + // Already at top + if ( 0 === thisItemPosition ) + break; + + // If a sub item is moved to top, shift it to 0 depth + if ( 0 === newItemPosition && 0 !== thisItemDepth ) + thisItem.moveHorizontally( 0, thisItemDepth ); + + // If prev item is sub item, shift to match depth + if ( 0 !== prevItemDepth ) + thisItem.moveHorizontally( prevItemDepth, thisItemDepth ); + + // Does this item have sub items? + if ( thisItemChildren ) { + var items = thisItem.add( thisItemChildren ); + // Move the entire block + items.detach().insertBefore( menuItems.eq( newItemPosition ) ); + } else { + thisItem.detach().insertBefore( menuItems.eq( newItemPosition ) ); + } + break; + case 'down': + // Does this item have sub items? + if ( thisItemChildren ) { + var items = thisItem.add( thisItemChildren ), + nextItem = menuItems.eq( items.length + thisItemPosition ), + nextItemChildren = 0 !== nextItem.childMenuItems().length; + + if ( nextItemChildren ) { + var newDepth = parseInt( nextItem.menuItemDepth() ) + 1; + thisItem.moveHorizontally( newDepth, thisItemDepth ); + } + + // Have we reached the bottom? + if ( menuItemsCount === thisItemPosition + items.length ) + break; + + items.detach().insertAfter( menuItems.eq( thisItemPosition + items.length ) ); + } else { + // If next item has sub items, shift depth + if ( 0 !== nextItemChildren.length ) + thisItem.moveHorizontally( nextItemDepth, thisItemDepth ); + + // Have we reached the bottom + if ( menuItemsCount === thisItemPosition + 1 ) + break; + thisItem.detach().insertAfter( menuItems.eq( thisItemPosition + 1 ) ); + } + break; + case 'left': + // As far left as possible + if ( 0 === thisItemDepth ) + break; + thisItem.shiftHorizontally( -1 ); + break; + case 'right': + // Can't be sub item at top + if ( 0 === thisItemPosition ) + break; + // Already sub item of prevItem + if ( thisItemData['menu-item-parent-id'] === prevItemId ) + break; + thisItem.shiftHorizontally( 1 ); + break; + } + api.registerChange(); + // Put focus back on same menu item + $( '#edit-' + thisItemData['menu-item-db-id'] ).focus(); + return false; + }); + }).blur(function () { + $(this).off( 'keydown' ); + }); + }, + + messageFadeIn : function() { + var messages = $( '#message' ); + + // Visual change when users save menus multiple times in a row + messages.slideDown( 'slow' ); + }, + initToggles : function() { // init postboxes postboxes.add_postbox_toggles('nav-menus'); @@ -246,6 +409,9 @@ var wpNavMenu; body = $('body'), maxChildDepth, menuMaxDepth = initialMenuMaxDepth(); + if( 0 != $( '#menu-to-edit li' ).length ) + $( '.drag-instructions' ).show(); + // Use the right edge if RTL. menuEdge += api.isRTL ? api.menuList.width() : 0; @@ -308,6 +474,13 @@ var wpNavMenu; // Return child elements to the list children = transport.children().insertAfter(ui.item); + // Add "sub menu" description + var subMenuTitle = ui.item.find( '.item-title .is-submenu' ); + if ( 0 < currentDepth ) + subMenuTitle.show(); + else + subMenuTitle.hide(); + // Update depth classes if( depthChange != 0 ) { ui.item.updateDepthClass( currentDepth ); @@ -327,9 +500,6 @@ var wpNavMenu; ui.item[0].style.left = 'auto'; ui.item[0].style.right = 0; } - - // The width of the tab bar might have changed. Just in case. - api.refreshMenuTabs( true ); }, change: function(e, ui) { // Make sure the placeholder is inside the menu. @@ -461,6 +631,8 @@ var wpNavMenu; if( '' == $t.val() ) $t.addClass( name ).val( $t.data(name) ); }); + + $( '.blank-slate .input-with-default-title' ).focus(); }, attachThemeLocationsListeners : function() { @@ -572,8 +744,11 @@ var wpNavMenu; $.post( ajaxurl, params, function(menuMarkup) { var ins = $('#menu-instructions'); processMethod(menuMarkup, params); - if( ! ins.hasClass('menu-instructions-inactive') && ins.siblings().length ) - ins.addClass('menu-instructions-inactive'); + // Make it stand out a bit more visually, by adding a fadeIn + $( 'li.pending' ).hide().fadeIn('slow'); + $( '.drag-instructions' ).show(); + if( ! ins.hasClass( 'menu-instructions-inactive' ) && ins.siblings().length ) + ins.addClass( 'menu-instructions-inactive' ); callback(); }); }, @@ -586,10 +761,12 @@ var wpNavMenu; */ addMenuItemToBottom : function( menuMarkup, req ) { $(menuMarkup).hideAdvancedMenuItemFields().appendTo( api.targetList ); + api.initAccessibility(); }, addMenuItemToTop : function( menuMarkup, req ) { $(menuMarkup).hideAdvancedMenuItemFields().prependTo( api.targetList ); + api.initAccessibility(); }, attachUnsavedChangesListener : function() { @@ -604,7 +781,7 @@ var wpNavMenu; }; } else { // Make the post boxes read-only, as they can't be used yet - $('#menu-settings-column').find('input,select').prop('disabled', true).end().find('a').attr('href', '#').unbind('click'); + $( '#menu-settings-column' ).find( 'input,select' ).end().find( 'a' ).attr( 'href', '#' ).unbind( 'click' ); } }, @@ -688,139 +865,6 @@ var wpNavMenu; }); }, - initTabManager : function() { - var fixed = $('.nav-tabs-wrapper'), - fluid = fixed.children('.nav-tabs'), - active = fluid.children('.nav-tab-active'), - tabs = fluid.children('.nav-tab'), - tabsWidth = 0, - fixedRight, fixedLeft, - arrowLeft, arrowRight, resizeTimer, css = {}, - marginFluid = api.isRTL ? 'margin-right' : 'margin-left', - marginFixed = api.isRTL ? 'margin-left' : 'margin-right', - msPerPx = 2; - - /** - * Refreshes the menu tabs. - * Will show and hide arrows where necessary. - * Scrolls to the active tab by default. - * - * @param savePosition {boolean} Optional. Prevents scrolling so - * that the current position is maintained. Default false. - **/ - api.refreshMenuTabs = function( savePosition ) { - var fixedWidth = fixed.width(), - margin = 0, css = {}; - fixedLeft = fixed.offset().left; - fixedRight = fixedLeft + fixedWidth; - - if( !savePosition ) - active.makeTabVisible(); - - // Prevent space from building up next to the last tab if there's more to show - if( tabs.last().isTabVisible() ) { - margin = fixed.width() - tabsWidth; - margin = margin > 0 ? 0 : margin; - css[marginFluid] = margin + 'px'; - fluid.animate( css, 100, "linear" ); - } - - // Show the arrows only when necessary - if( fixedWidth > tabsWidth ) - arrowLeft.add( arrowRight ).hide(); - else - arrowLeft.add( arrowRight ).show(); - } - - $.fn.extend({ - makeTabVisible : function() { - var t = this.eq(0), left, right, css = {}, shift = 0; - - if( ! t.length ) return this; - - left = t.offset().left; - right = left + t.outerWidth(); - - if( right > fixedRight ) - shift = fixedRight - right; - else if ( left < fixedLeft ) - shift = fixedLeft - left; - - if( ! shift ) return this; - - css[marginFluid] = "+=" + api.negateIfRTL * shift + 'px'; - fluid.animate( css, Math.abs( shift ) * msPerPx, "linear" ); - return this; - }, - isTabVisible : function() { - var t = this.eq(0), - left = t.offset().left, - right = left + t.outerWidth(); - return ( right <= fixedRight && left >= fixedLeft ) ? true : false; - } - }); - - // Find the width of all tabs - tabs.each(function(){ - tabsWidth += $(this).outerWidth(true); - }); - - // Set up fixed margin for overflow, unset padding - css['padding'] = 0; - css[marginFixed] = (-1 * tabsWidth) + 'px'; - fluid.css( css ); - - // Build tab navigation - arrowLeft = $('<div class="nav-tabs-arrow nav-tabs-arrow-left"><a>«</a></div>'); - arrowRight = $('<div class="nav-tabs-arrow nav-tabs-arrow-right"><a>»</a></div>'); - // Attach to the document - fixed.wrap('<div class="nav-tabs-nav"/>').parent().prepend( arrowLeft ).append( arrowRight ); - - // Set the menu tabs - api.refreshMenuTabs(); - // Make sure the tabs reset on resize - $(window).resize(function() { - if( resizeTimer ) clearTimeout(resizeTimer); - resizeTimer = setTimeout( api.refreshMenuTabs, 200); - }); - - // Build arrow functions - $.each([{ - arrow : arrowLeft, - next : "next", - last : "first", - operator : "+=" - },{ - arrow : arrowRight, - next : "prev", - last : "last", - operator : "-=" - }], function(){ - var that = this; - this.arrow.mousedown(function(){ - var marginFluidVal = Math.abs( parseInt( fluid.css(marginFluid) ) ), - shift = marginFluidVal, - css = {}; - - if( "-=" == that.operator ) - shift = Math.abs( tabsWidth - fixed.width() ) - marginFluidVal; - - if( ! shift ) return; - - css[marginFluid] = that.operator + shift + 'px'; - fluid.animate( css, shift * msPerPx, "linear" ); - }).mouseup(function(){ - var tab, next; - fluid.stop(true); - tab = tabs[that.last](); - while( (next = tab[that.next]()) && next.length && ! next.isTabVisible() ) { - tab = next; - } - tab.makeTabVisible(); - }); - }); - }, - eventOnClickEditLink : function(clickedEl) { var settings, item, matchedSection = /#(.*)$/.exec(clickedEl.href); @@ -846,8 +890,10 @@ var wpNavMenu; }, eventOnClickCancelLink : function(clickedEl) { - var settings = $(clickedEl).closest('.menu-item-settings'); - settings.setItemData( settings.data('menu-item-data') ); + var settings = $( clickedEl ).closest( '.menu-item-settings' ), + thisMenuItem = $( clickedEl ).closest( '.menu-item' ); + thisMenuItem.removeClass('menu-item-edit-active').addClass('menu-item-edit-inactive'); + settings.setItemData( settings.data('menu-item-data') ).hide(); return false; }, @@ -944,9 +990,11 @@ var wpNavMenu; }, 350, function() { var ins = $('#menu-instructions'); el.remove(); - children.shiftDepthClass(-1).updateParentMenuItemDBId(); - if( ! ins.siblings().length ) - ins.removeClass('menu-instructions-inactive'); + children.shiftDepthClass( -1 ).updateParentMenuItemDBId(); + if( 0 == $( '#menu-to-edit li' ).length ) { + $( '.drag-instructions' ).hide(); + ins.removeClass( 'menu-instructions-inactive' ); + } }); }, diff --git a/wp-admin/nav-menus.php b/wp-admin/nav-menus.php index 98f95a0e0d..9ac0d76881 100644 --- a/wp-admin/nav-menus.php +++ b/wp-admin/nav-menus.php @@ -221,49 +221,64 @@ switch ( $action ) { if ( is_nav_menu_item( $menu_item_id ) && wp_delete_post( $menu_item_id, true ) ) $messages[] = '<div id="message" class="updated"><p>' . __('The menu item has been successfully deleted.') . '</p></div>'; break; + case 'delete': check_admin_referer( 'delete-nav_menu-' . $nav_menu_selected_id ); - if ( is_nav_menu( $nav_menu_selected_id ) ) { - $deleted_nav_menu = wp_get_nav_menu_object( $nav_menu_selected_id ); - $delete_nav_menu = wp_delete_nav_menu( $nav_menu_selected_id ); - - if ( is_wp_error($delete_nav_menu) ) { - $messages[] = '<div id="message" class="error"><p>' . $delete_nav_menu->get_error_message() . '</p></div>'; - } else { - // Remove this menu from any locations. - $locations = get_theme_mod( 'nav_menu_locations' ); - foreach ( (array) $locations as $location => $menu_id ) { - if ( $menu_id == $nav_menu_selected_id ) - $locations[ $location ] = 0; - } - set_theme_mod( 'nav_menu_locations', $locations ); - $messages[] = '<div id="message" class="updated"><p>' . __('The menu has been successfully deleted.') . '</p></div>'; - // Select the next available menu - $nav_menu_selected_id = 0; - $_nav_menus = wp_get_nav_menus( array('orderby' => 'name') ); - foreach( $_nav_menus as $index => $_nav_menu ) { - if ( strcmp( $_nav_menu->name, $deleted_nav_menu->name ) >= 0 - || $index == count( $_nav_menus ) - 1 ) { - $nav_menu_selected_id = $_nav_menu->term_id; - break; - } - } - } - unset( $delete_nav_menu, $deleted_nav_menu, $_nav_menus ); + $deletion = _wp_delete_nav_menu( $nav_menu_selected_id ); } else { // Reset the selected menu $nav_menu_selected_id = 0; unset( $_REQUEST['menu'] ); } + + if ( ! isset( $deletion ) ) + break; + + if ( is_wp_error( $deletion ) ) + $messages[] = '<div id="message" class="error"><p>' . $deletion->get_error_message() . '</p></div>'; + else + $messages[] = '<div id="message" class="updated"><p>' . __( 'The menu has been successfully deleted.' ) . '</p></div>'; + break; + + case 'delete_menus': + check_admin_referer( 'nav_menus_bulk_actions' ); + foreach ( $_REQUEST['delete_menus'] as $menu_id_to_delete ) { + if ( ! is_nav_menu( $menu_id_to_delete ) ) + continue; + + $deletion = _wp_delete_nav_menu( $menu_id_to_delete ); + if ( is_wp_error( $deletion ) ) { + $messages[] = '<div id="message" class="error"><p>' . $deletion->get_error_message() . '</p></div>'; + $deletion_error = true; + } + } + + if ( empty( $deletion_error ) ) + $messages[] = '<div id="message" class="updated"><p>' . __( 'Selected menus have been successfully deleted.' ) . '</p></div>'; break; case 'update': check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' ); - // Update menu theme locations - if ( isset( $_POST['menu-locations'] ) ) - set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) ); + // Get existing menu locations assignments + $locations = get_registered_nav_menus(); + $menu_locations = get_nav_menu_locations(); + + // Remove menu locations that have been unchecked + foreach ( $locations as $location => $description ) { + if ( ( empty( $_POST['menu-locations'] ) || empty( $_POST['menu-locations'][ $location ] ) ) && isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] == $nav_menu_selected_id ) + unset( $menu_locations[ $location ] ); + } + + // Merge new and existing menu locations if any new ones are set + if ( isset( $_POST['menu-locations'] ) ) { + $new_menu_locations = array_map( 'absint', $_POST['menu-locations'] ); + $menu_locations = array_merge( $menu_locations, $new_menu_locations ); + } + + // Set menu locations + set_theme_mod( 'nav_menu_locations', $menu_locations ); // Add Menu if ( 0 == $nav_menu_selected_id ) { @@ -278,20 +293,33 @@ switch ( $action ) { $_menu_object = wp_get_nav_menu_object( $_nav_menu_selected_id ); $nav_menu_selected_id = $_nav_menu_selected_id; $nav_menu_selected_title = $_menu_object->name; - $messages[] = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been successfully created.'), $nav_menu_selected_title ) . '</p></div>'; + if ( isset( $_REQUEST['menu-item'] ) ) + wp_save_nav_menu_items( $nav_menu_selected_id, absint( $_REQUEST['menu-item'] ) ); + if ( isset( $_REQUEST['zero-menu-state'] ) ) { + // If there are menu items, add them + wp_nav_menu_update_menu_items( $nav_menu_selected_id, $nav_menu_selected_title ); + // Auto-save nav_menu_locations + $locations = get_theme_mod( 'nav_menu_locations' ); + foreach ( (array) $locations as $location => $menu_id ) { + $locations[ $location ] = $nav_menu_selected_id; + break; // There should only be 1 + } + set_theme_mod( 'nav_menu_locations', $locations ); + } + $messages[] = '<div id="message" class="updated"><p>' . sprintf( __( '<strong>%s</strong> has been created.' ), $nav_menu_selected_title ) . '</p></div>'; } } else { - $messages[] = '<div id="message" class="error"><p>' . __('Please enter a valid menu name.') . '</p></div>'; + $messages[] = '<div id="message" class="error"><p>' . __( 'Please enter a valid menu name.' ) . '</p></div>'; } - // update existing menu + // Update existing menu } else { $_menu_object = wp_get_nav_menu_object( $nav_menu_selected_id ); $menu_title = trim( esc_html( $_POST['menu-name'] ) ); if ( ! $menu_title ) { - $messages[] = '<div id="message" class="error"><p>' . __('Please enter a valid menu name.') . '</p></div>'; + $messages[] = '<div id="message" class="error"><p>' . __( 'Please enter a valid menu name.' ) . '</p></div>'; $menu_title = $_menu_object->name; } @@ -307,68 +335,8 @@ switch ( $action ) { } // Update menu items - if ( ! is_wp_error( $_menu_object ) ) { - $unsorted_menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array('orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID', 'post_status' => 'draft,publish') ); - $menu_items = array(); - // Index menu items by db ID - foreach( $unsorted_menu_items as $_item ) - $menu_items[$_item->db_id] = $_item; - - $post_fields = array( 'menu-item-db-id', 'menu-item-object-id', 'menu-item-object', 'menu-item-parent-id', 'menu-item-position', 'menu-item-type', 'menu-item-title', 'menu-item-url', 'menu-item-description', 'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn' ); - wp_defer_term_counting(true); - // Loop through all the menu items' POST variables - if ( ! empty( $_POST['menu-item-db-id'] ) ) { - foreach( (array) $_POST['menu-item-db-id'] as $_key => $k ) { - - // Menu item title can't be blank - if ( empty( $_POST['menu-item-title'][$_key] ) ) - continue; - - $args = array(); - foreach ( $post_fields as $field ) - $args[$field] = isset( $_POST[$field][$_key] ) ? $_POST[$field][$_key] : ''; - - $menu_item_db_id = wp_update_nav_menu_item( $nav_menu_selected_id, ( $_POST['menu-item-db-id'][$_key] != $_key ? 0 : $_key ), $args ); - - if ( is_wp_error( $menu_item_db_id ) ) - $messages[] = '<div id="message" class="error"><p>' . $menu_item_db_id->get_error_message() . '</p></div>'; - elseif ( isset( $menu_items[$menu_item_db_id] ) ) - unset( $menu_items[$menu_item_db_id] ); - } - } - - // Remove menu items from the menu that weren't in $_POST - if ( ! empty( $menu_items ) ) { - foreach ( array_keys( $menu_items ) as $menu_item_id ) { - if ( is_nav_menu_item( $menu_item_id ) ) { - wp_delete_post( $menu_item_id ); - } - } - } - - // Store 'auto-add' pages. - $auto_add = ! empty( $_POST['auto-add-pages'] ); - $nav_menu_option = (array) get_option( 'nav_menu_options' ); - if ( ! isset( $nav_menu_option['auto_add'] ) ) - $nav_menu_option['auto_add'] = array(); - if ( $auto_add ) { - if ( ! in_array( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) ) - $nav_menu_option['auto_add'][] = $nav_menu_selected_id; - } else { - if ( false !== ( $key = array_search( $nav_menu_selected_id, $nav_menu_option['auto_add'] ) ) ) - unset( $nav_menu_option['auto_add'][$key] ); - } - // Remove nonexistent/deleted menus - $nav_menu_option['auto_add'] = array_intersect( $nav_menu_option['auto_add'], wp_get_nav_menus( array( 'fields' => 'ids' ) ) ); - update_option( 'nav_menu_options', $nav_menu_option ); - - wp_defer_term_counting(false); - - do_action( 'wp_update_nav_menu', $nav_menu_selected_id ); - - $messages[] = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been updated.'), $nav_menu_selected_title ) . '</p></div>'; - unset( $menu_items, $unsorted_menu_items ); + $messages = array_merge( $messages, wp_nav_menu_update_menu_items( $nav_menu_selected_id, $nav_menu_selected_title ) ); } } break; @@ -376,22 +344,35 @@ switch ( $action ) { // Get all nav menus $nav_menus = wp_get_nav_menus( array('orderby' => 'name') ); +$menu_count = count( $nav_menus ); -// Get recently edited nav menu -$recently_edited = (int) get_user_option( 'nav_menu_recently_edited' ); +// Are we on the add new screen? +$add_new_screen = ( isset( $_GET['menu'] ) && 0 == $_GET['menu'] ) ? true : false; -// If there was no recently edited menu, and $nav_menu_selected_id is a nav menu, update recently edited menu. -if ( !$recently_edited && is_nav_menu( $nav_menu_selected_id ) ) { +// If we have one theme location, and zero menus, we take them right into editing their first menu +$page_count = wp_count_posts( 'page' ); +$one_theme_location_no_menus = ( 1 == count( get_registered_nav_menus() ) && ! $add_new_screen && empty( $nav_menus ) && ! empty( $page_count->publish ) ) ? true : false; + +// Redirect to add screen if there are no menus and this users has either zero, or more than 1 theme locations +if ( 0 == $menu_count && ! $add_new_screen && ! $one_theme_location_no_menus ) + wp_redirect( admin_url( 'nav-menus.php?action=edit&menu=0' ) ); + +// Get recently edited nav menu +$recently_edited = absint( get_user_option( 'nav_menu_recently_edited' ) ); +if ( empty( $recently_edited ) && is_nav_menu( $nav_menu_selected_id ) ) $recently_edited = $nav_menu_selected_id; -// Else if $nav_menu_selected_id is not a menu and not requesting that we create a new menu, but $recently_edited is a menu, grab that one. -} elseif ( 0 == $nav_menu_selected_id && ! isset( $_REQUEST['menu'] ) && is_nav_menu( $recently_edited ) ) { +// Use $recently_edited if none are selected +if ( empty( $nav_menu_selected_id ) && ! isset( $_GET['menu'] ) && is_nav_menu( $recently_edited ) ) $nav_menu_selected_id = $recently_edited; -// Else try to grab the first menu from the menus list -} elseif ( 0 == $nav_menu_selected_id && ! isset( $_REQUEST['menu'] ) && ! empty($nav_menus) ) { +// On deletion of menu, if another menu exists, show it +if ( ! $add_new_screen && 0 < $menu_count && isset( $_GET['action'] ) && 'delete' == $_GET['action'] ) $nav_menu_selected_id = $nav_menus[0]->term_id; -} + +// Set $nav_menu_selected_id to 0 if no menus +if ( $one_theme_location_no_menus ) + $nav_menu_selected_id = 0; // Update the user's setting if ( $nav_menu_selected_id != $recently_edited && is_nav_menu( $nav_menu_selected_id ) ) @@ -412,14 +393,22 @@ foreach( (array) $nav_menus as $key => $_nav_menu ) { $nav_menus[$key]->truncated_name = $_nav_menu->truncated_name; } +// Retrieve menu locations +if ( current_theme_supports( 'menus' ) ) { + $locations = get_registered_nav_menus(); + $menu_locations = get_nav_menu_locations(); +} + // Ensure the user will be able to scroll horizontally // by adding a class for the max menu depth. global $_wp_nav_menu_max_depth; $_wp_nav_menu_max_depth = 0; // Calling wp_get_nav_menu_to_edit generates $_wp_nav_menu_max_depth -if ( is_nav_menu( $nav_menu_selected_id ) ) +if ( is_nav_menu( $nav_menu_selected_id ) ) { + $menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array( 'post_status' => 'any' ) ); $edit_markup = wp_get_nav_menu_to_edit( $nav_menu_selected_id ); +} function wp_nav_menu_max_depth($classes) { global $_wp_nav_menu_max_depth; @@ -460,14 +449,51 @@ require_once( './admin-header.php' ); ?> <div class="wrap"> <?php screen_icon(); ?> - <h2><?php esc_html_e('Menus'); ?></h2> + <h2><?php _e( 'Menus' ); ?> <a href="<?php echo esc_url( add_query_arg( array( 'action' => 'edit', 'menu' => 0, ), admin_url( 'nav-menus.php' ) ) ); ?>" class="add-new-h2"><?php _e( 'Add New' ); ?></a></h2> <?php foreach( $messages as $message ) : echo $message . "\n"; endforeach; ?> + <?php if ( 1 < $menu_count ) : ?> + <form method="post" action="<?php echo admin_url( 'nav-menus.php' ); ?>"> + <input type="hidden" name="action" value="edit" /> + <div class="manage-menus"> + <label for="menu" class="selected-menu"><?php _e('Select menu to edit'); ?></label> + <select name="menu" id="menu"> + <?php if ( $add_new_screen ) : ?> + <option value="0" selected="selected"><?php _e( '-- Select --' ); ?></option> + <?php endif; ?> + <?php foreach( (array) $nav_menus as $_nav_menu ) : ?> + <option value="<?php echo esc_attr( $_nav_menu->term_id ); ?>" <?php selected( $_nav_menu->term_id, $nav_menu_selected_id ); ?>> + <?php + echo esc_html( $_nav_menu->truncated_name ) ; + + if ( ! empty( $menu_locations ) && in_array( $_nav_menu->term_id, $menu_locations ) ) { + $locations_assigned_to_this_menu = array(); + foreach ( array_keys( $menu_locations, $_nav_menu->term_id ) as $menu_location_key ) { + $locations_assigned_to_this_menu[] = $locations[ $menu_location_key ]; + } + $assigned_locations = array_slice( $locations_assigned_to_this_menu, 0, absint( apply_filters( 'wp_nav_locations_listed_per_menu', 3 ) ) ); + + // Adds ellipses following the number of locations defined in $assigned_locations + printf( ' (%1$s%2$s)', + implode( ', ', $assigned_locations ), + count( $locations_assigned_to_this_menu ) > count( $assigned_locations ) ? ' …' : '' + ); + } + ?> + </option> + <?php endforeach; ?> + </select> + <span class="submit-btn"><input type="submit" class="button-secondary" value="<?php _e( 'Select' ); ?>"></span> + </div> + </form> + <?php endif; ?> <div id="nav-menus-frame"> - <div id="menu-settings-column" class="metabox-holder<?php if ( !$nav_menu_selected_id ) { echo ' metabox-holder-disabled'; } ?>"> + <div id="menu-settings-column" class="metabox-holder<?php if ( isset( $_GET['menu'] ) && '0' == $_GET['menu'] ) { echo ' metabox-holder-disabled'; } ?>"> + + <div class="clear"></div> <form id="nav-menu-meta" action="<?php echo admin_url( 'nav-menus.php' ); ?>" class="nav-menu-meta" method="post" enctype="multipart/form-data"> <input type="hidden" name="menu" id="nav-menu-meta-object-id" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> @@ -479,129 +505,100 @@ require_once( './admin-header.php' ); </div><!-- /#menu-settings-column --> <div id="menu-management-liquid"> <div id="menu-management"> - <div id="select-nav-menu-container" class="hide-if-js"> - <form id="select-nav-menu" action=""> - <strong><label for="select-nav-menu"><?php esc_html_e( 'Select Menu:' ); ?></label></strong> - <select class="select-nav-menu" name="menu"> - <?php foreach( (array) $nav_menus as $_nav_menu ) : ?> - <option value="<?php echo esc_attr($_nav_menu->term_id) ?>" <?php selected($nav_menu_selected_id, $_nav_menu->term_id); ?>> - <?php echo esc_html( $_nav_menu->truncated_name ); ?> - </option> - <?php endforeach; ?> - <option value="0"><?php esc_html_e('Add New Menu'); ?></option> - </select> - <input type="hidden" name="action" value="edit" /> - <?php submit_button( __( 'Select' ), 'secondary', 'select_menu', false ); ?> - </form> - </div> - <div class="nav-tabs-wrapper"> - <div class="nav-tabs"> - <?php - foreach( (array) $nav_menus as $_nav_menu ) : - if ( $nav_menu_selected_id == $_nav_menu->term_id ) : ?><span class="nav-tab nav-tab-active"> - <?php echo esc_html( $_nav_menu->truncated_name ); ?> - </span><?php else : ?><a href="<?php - echo esc_url(add_query_arg( - array( - 'action' => 'edit', - 'menu' => $_nav_menu->term_id, - ), - admin_url( 'nav-menus.php' ) - )); - ?>" class="nav-tab hide-if-no-js"> - <?php echo esc_html( $_nav_menu->truncated_name ); ?> - </a><?php endif; - endforeach; - if ( 0 == $nav_menu_selected_id ) : ?><span class="nav-tab menu-add-new nav-tab-active"> - <?php printf( '<abbr title="%s">+</abbr>', esc_html__( 'Add menu' ) ); ?> - </span><?php else : ?><a href="<?php - echo esc_url(add_query_arg( - array( - 'action' => 'edit', - 'menu' => 0, - ), - admin_url( 'nav-menus.php' ) - )); - ?>" class="nav-tab menu-add-new"> - <?php printf( '<abbr title="%s">+</abbr>', esc_html__( 'Add menu' ) ); ?> - </a><?php endif; ?> - </div> - </div> - <div class="menu-edit"> - <form id="update-nav-menu" action="<?php echo admin_url( 'nav-menus.php' ); ?>" method="post" enctype="multipart/form-data"> + <form id="update-nav-menu" action="<?php echo esc_url( admin_url( 'nav-menus.php' ) ); ?>" method="post" enctype="multipart/form-data"> + <div class="menu-edit <?php if ( $add_new_screen ) echo 'blank-slate'; ?>"> + <?php + wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); + wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); + wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' ); + + if ( $one_theme_location_no_menus ) { ?> + <input type="hidden" name="zero-menu-state" value="true" /> + <?php } ?> + <input type="hidden" name="action" value="update" /> + <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> <div id="nav-menu-header"> - <div id="submitpost" class="submitbox"> - <div class="major-publishing-actions"> - <label class="menu-name-label howto open-label" for="menu-name"> - <span><?php _e('Menu Name'); ?></span> - <input name="menu-name" id="menu-name" type="text" class="menu-name regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e('Enter menu name here'); ?>" value="<?php echo esc_attr( $nav_menu_selected_title ); ?>" /> - </label> - <?php if ( !empty( $nav_menu_selected_id ) ) : - if ( ! isset( $auto_add ) ) { - $auto_add = get_option( 'nav_menu_options' ); - if ( ! isset( $auto_add['auto_add'] ) ) - $auto_add = false; - elseif ( false !== array_search( $nav_menu_selected_id, $auto_add['auto_add'] ) ) - $auto_add = true; - else - $auto_add = false; - } - ?> - <div class="auto-add-pages"> - <label class="howto"><input type="checkbox"<?php checked( $auto_add ); ?> name="auto-add-pages" value="1" /> <?php printf( __('Automatically add new top-level pages' ), esc_url( admin_url( 'edit.php?post_type=page' ) ) ); ?></label> - </div> - <?php endif; ?> - <br class="clear" /> - <div class="publishing-action"> - <?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?> - </div><!-- END .publishing-action --> - - <?php if ( ! empty( $nav_menu_selected_id ) ) : ?> - <div class="delete-action"> - <a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( admin_url('nav-menus.php?action=delete&menu=' . $nav_menu_selected_id), 'delete-nav_menu-' . $nav_menu_selected_id ) ); ?>"><?php _e('Delete Menu'); ?></a> - </div><!-- END .delete-action --> - <?php endif; ?> - </div><!-- END .major-publishing-actions --> - </div><!-- END #submitpost .submitbox --> - <?php - wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); - wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); - wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' ); - ?> - <input type="hidden" name="action" value="update" /> - <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> - </div><!-- END #nav-menu-header --> + <div class="major-publishing-actions"> + <label class="menu-name-label howto open-label" for="menu-name"> + <span><?php _e( 'Menu Name' ); ?></span> + <input name="menu-name" id="menu-name" type="text" class="menu-name regular-text menu-item-textbox input-with-default-title" title="<?php esc_attr_e( 'Enter menu name here' ); ?>" value="<?php if ( $one_theme_location_no_menus ) _e( 'Menu 1' ); else echo esc_attr( $nav_menu_selected_title ); ?>" /> + </label> + <div class="publishing-action"> + <?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?> + </div><!-- END .publishing-action --> + </div><!-- END .major-publishing-actions --> + </div><!-- END .nav-menu-header --> <div id="post-body"> <div id="post-body-content"> + <?php if ( ! $add_new_screen ) : ?> + <?php $starter_copy = ( $one_theme_location_no_menus ) ? __( 'Edit your default menu by adding or removing items. Drag each item into the order you prefer. Click Create Menu to save your changes.' ) : __( 'Drag each item into the order you prefer. Click an item to reveal additional configuration options.' ); ?> + <div class="drag-instructions post-body-plain" <?php if ( isset( $menu_items ) && 0 == count( $menu_items ) ) { ?>style="display: none;"<?php } ?>> + <p><?php echo $starter_copy; ?></p> + </div> <?php - if ( isset( $edit_markup ) ) { - if ( ! is_wp_error( $edit_markup ) ) - echo $edit_markup; - } else if ( empty( $nav_menu_selected_id ) ) { - echo '<div class="post-body-plain">'; - echo '<p>' . __('To create a custom menu, give it a name above and click Create Menu. Then choose items like pages, categories or custom links from the left column to add to this menu.') . '</p>'; - echo '<p>' . __('After you have added your items, drag and drop to put them in the order you want. You can also click each item to reveal additional configuration options.') . '</p>'; - echo '<p>' . __('When you have finished building your custom menu, make sure you click the Save Menu button.') . '</p>'; - echo '</div>'; - } + if ( isset( $edit_markup ) && ! is_wp_error( $edit_markup ) ) { + echo $edit_markup; + } else { ?> + <ul class="menu" id="menu-to-edit"></ul> + <?php } ?> + <?php endif; ?> + <?php if ( $add_new_screen ) : ?> + <p class="post-body-plain"><?php _e( 'Give your menu a name above, then click Create Menu.' ); ?></p> + <?php endif; ?> + <div class="menu-settings" <?php if ( $one_theme_location_no_menus ) { ?>style="display: none;"<?php } ?>> + <?php + if ( ! isset( $auto_add ) ) { + $auto_add = get_option( 'nav_menu_options' ); + if ( ! isset( $auto_add['auto_add'] ) ) + $auto_add = false; + elseif ( false !== array_search( $nav_menu_selected_id, $auto_add['auto_add'] ) ) + $auto_add = true; + else + $auto_add = false; + } ?> + + <dl class="auto-add-pages"> + <dt class="howto"><?php _e( 'Auto add pages' ); ?></dt> + <dd class="checkbox-input"><input type="checkbox"<?php checked( $auto_add ); ?> name="auto-add-pages" id="auto-add-pages" value="1" /> <label for="auto-add-pages"><?php printf( __('Automatically add new top-level pages to this menu' ), esc_url( admin_url( 'edit.php?post_type=page' ) ) ); ?></label></dd> + </dl> + + <?php if ( current_theme_supports( 'menus' ) ) : ?> + + <dl class="menu-theme-locations"> + <dt class="howto"><?php _e( 'Theme locations' ); ?></dt> + <?php foreach ( $locations as $location => $description ) : ?> + <dd class="checkbox-input"> + <input type="checkbox"<?php checked( isset( $menu_locations[ $location ] ) && $menu_locations[ $location ] == $nav_menu_selected_id ); ?> name="menu-locations[<?php echo esc_attr( $location ); ?>]" id="locations-<?php echo esc_attr( $location ); ?>" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> <label for="locations-<?php echo esc_attr( $location ); ?>"><?php echo $description; ?></label> + <?php if ( ! empty( $menu_locations[ $location ] ) && $menu_locations[ $location ] != $nav_menu_selected_id ) : ?> + <span class="theme-location-set"> <?php printf( __( "(Currently set to: %s)" ), wp_get_nav_menu_object( $menu_locations[ $location ] )->name ); ?> </span> + <?php endif; ?> + </dd> + <?php endforeach; ?> + </dl> + + <?php endif; ?> + + </div> </div><!-- /#post-body-content --> </div><!-- /#post-body --> <div id="nav-menu-footer"> <div class="major-publishing-actions"> - <div class="publishing-action"> - <?php - if ( ! empty( $nav_menu_selected_id ) ) - submit_button( __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_footer' ) ); - ?> - </div> - </div> + <?php if ( 0 != $menu_count && ! $add_new_screen ) : ?> + <span class="delete-action"> + <a class="submitdelete deletion menu-delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'menu' => $nav_menu_selected_id, admin_url() ) ), 'delete-nav_menu-' . $nav_menu_selected_id) ); ?>"><?php _e('Delete Menu'); ?></a> + </span><!-- END .delete-action --> + <?php endif; ?> + <div class="publishing-action"> + <?php submit_button( empty( $nav_menu_selected_id ) ? __( 'Create Menu' ) : __( 'Save Menu' ), 'button-primary menu-save', 'save_menu', false, array( 'id' => 'save_menu_header' ) ); ?> + </div><!-- END .publishing-action --> + </div><!-- END .major-publishing-actions --> </div><!-- /#nav-menu-footer --> - </form><!-- /#update-nav-menu --> - </div><!-- /.menu-edit --> + </div><!-- /.menu-edit --> + </form><!-- /#update-nav-menu --> </div><!-- /#menu-management --> </div><!-- /#menu-management-liquid --> </div><!-- /#nav-menus-frame --> </div><!-- /.wrap--> - +<script type="text/javascript">var oneThemeLocationNoMenus = <?php if ( $one_theme_location_no_menus ) echo 'true'; else echo 'false'; ?>;</script> <?php include( './admin-footer.php' ); ?> |