More nav menu fixes. props filosofo. see #13148. fixes #13155, fixes #13157, fixes #13138, see #13134.

git-svn-id: http://svn.automattic.com/wordpress/trunk@14283 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
nacin 2010-04-28 18:30:32 +00:00
parent f0b91458e4
commit 8c9f71bb57
7 changed files with 154 additions and 49 deletions

View File

@ -305,12 +305,15 @@ function wp_initial_nav_menu_meta_boxes() {
function wp_nav_menu_post_type_meta_boxes() {
$post_types = get_post_types( array( 'public' => true ), 'object' );
if ( !$post_types )
if ( ! $post_types )
return;
foreach ( $post_types as $post_type ) {
$id = $post_type->name;
add_meta_box( "add-{$id}", $post_type->label, 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type );
$post_type = apply_filters( 'nav_menu_meta_box_object', $post_type );
if ( $post_type ) {
$id = $post_type->name;
add_meta_box( "add-{$id}", $post_type->label, 'wp_nav_menu_item_post_type_meta_box', 'nav-menus', 'side', 'default', $post_type );
}
}
}
@ -326,8 +329,11 @@ function wp_nav_menu_taxonomy_meta_boxes() {
return;
foreach ( $taxonomies as $tax ) {
$id = $tax->name;
add_meta_box( "add-{$id}", $tax->label, 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax );
$tax = apply_filters( 'nav_menu_meta_box_object', $tax );
if ( $tax ) {
$id = $tax->name;
add_meta_box( "add-{$id}", $tax->label, 'wp_nav_menu_item_taxonomy_meta_box', 'nav-menus', 'side', 'default', $tax );
}
}
}
@ -337,8 +343,8 @@ function wp_nav_menu_taxonomy_meta_boxes() {
* @since 3.0.0
*/
function wp_nav_menu_item_link_meta_box() {
static $_placeholder;
$_placeholder = 0 > $_placeholder ? $_placeholder - 1 : -1;
global $_nav_menu_placeholder;
$_nav_menu_placeholder = 0 > $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1;
// @note: hacky query, see #12660
$args = array( 'post_type' => 'nav_menu_item', 'post_status' => 'any', 'meta_key' => '_menu_item_type', 'numberposts' => -1, 'orderby' => 'title', );
@ -364,39 +370,27 @@ function wp_nav_menu_item_link_meta_box() {
<div class="customlinkdiv">
<ul id="customlink-tabs" class="customlink-tabs add-menu-item-tabs">
<li <?php echo ( 'create' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg('customlink-tab', 'create', remove_query_arg($removed_args)); ?>#tabs-panel-create-custom"><?php _e('Create New'); ?></a></li>
<li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="menu-tab-link" href="<?php echo add_query_arg('customlink-tab', 'all', remove_query_arg($removed_args)); ?>#tabs-panel-all-custom"><?php _e('View All'); ?></a></li>
</ul>
<div class="tabs-panel <?php
echo ( 'create' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
?>" id="tabs-panel-create-custom">
<input type="hidden" value="custom" name="menu-item[<?php echo $_placeholder; ?>][menu-item-type]" />
<input type="hidden" value="custom" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-type]" />
<p id="menu-item-url-wrap">
<label class="howto" for="custom-menu-item-url">
<span><?php _e('URL'); ?></span>
<input id="custom-menu-item-url" name="menu-item[<?php echo $_placeholder; ?>][menu-item-url]" type="text" class="code menu-item-textbox" value="http://" />
<input id="custom-menu-item-url" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-url]" type="text" class="code menu-item-textbox" value="http://" />
</label>
</p>
<p id="menu-item-name-wrap">
<label class="howto" for="custom-menu-item-name">
<span><?php _e('Text'); ?></span>
<input id="custom-menu-item-name" name="menu-item[<?php echo $_placeholder; ?>][menu-item-title]" type="text" class="regular-text menu-item-textbox" value="<?php echo esc_attr( __('Menu Item') ); ?>" />
<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" value="<?php echo esc_attr( __('Menu Item') ); ?>" />
</label>
</p>
</div><!-- /.tabs-panel -->
<div class="tabs-panel <?php
echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' );
?>" id="tabs-panel-all-custom">
<ul id="customlinkchecklist" class="list:customlink customlinkchecklist form-no-clear">
<?php
$args['walker'] = new Walker_Nav_Menu_Checklist;
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $links), 0, (object) $args );
?>
</ul>
</div><!-- /.tabs-panel -->
<p class="button-controls">
<span class="add-to-menu">
<input type="submit" class="button-secondary" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-custom-menu-item" />
@ -433,6 +427,9 @@ function wp_nav_menu_item_post_type_meta_box( $object, $post_type ) {
'suppress_filters' => true,
);
if ( isset( $post_type['args']->_default_query ) )
$args = array_merge($args, (array) $post_type['args']->_default_query );
// @todo transient caching of these results with proper invalidation on updating of a post of this type
$get_posts = new WP_Query;
$posts = $get_posts->query( $args );
@ -809,6 +806,48 @@ function wp_save_nav_menu_item( $menu_id = 0, $menu_data = array() ) {
return $items_saved;
}
/**
* Adds custom arguments to some of the meta box object types.
*
* @since 3.0.0
*
* @access private
*
* @param object $object The post type or taxonomy meta-object.
* @return object The post type of taxonomy object.
*/
function _wp_nav_menu_meta_box_object( $object = null ) {
if ( isset( $object->name ) ) {
// don't show media meta box
if ( 'attachment' == $object->name )
return false;
// pages should show most recent
if ( 'page' == $object->name ) {
$object->_default_query = array(
'orderby' => 'post_date',
'order' => 'DESC',
'post_status' => 'publish',
);
// posts should show only published items
} elseif ( 'post' == $object->name ) {
$object->_default_query = array(
'post_status' => 'publish',
);
// cats should be in reverse chronological order
} elseif ( 'category' == $object->name ) {
$object->_default_query = array(
'orderby' => 'id',
'order' => 'DESC',
);
}
}
return $object;
}
/**
* Returns the menu item formatted to edit.
*
@ -818,8 +857,6 @@ function wp_save_nav_menu_item( $menu_id = 0, $menu_data = array() ) {
* @return string|WP_Error $output The menu formatted to edit or error object on failure.
*/
function wp_get_nav_menu_to_edit( $menu_item_id = 0 ) {
static $_placeholder;
$menu = wp_get_nav_menu_object( $menu_item_id );
// If the menu exists, get its items.

View File

@ -159,8 +159,16 @@ var WPNavMenuHandler = function () {
if ( ! list )
return;
var menuListItems = list.getElementsByTagName('li'),
var dummyListItem = document.getElementById(list.id + '-dummy-list-item'),
menuListItems = list.getElementsByTagName('li'),
i = menuListItems.length;
if ( ! dummyListItem ) {
dummyListItem = document.createElement('li');
dummyListItem.id = list.id + '-dummy-list-item';
list.appendChild(dummyListItem);
this.setupListItemDragAndDrop(dummyListItem);
}
while ( i-- )
this.setupListItemDragAndDrop(menuListItems[i]);
@ -234,19 +242,23 @@ var WPNavMenuHandler = function () {
attachTabsPanelListeners : function() {
$('#menu-settings-column').bind('click', function(e) {
if ( e.target && e.target.className && -1 != e.target.className.indexOf('menu-tab-link') ) {
var i = e.target.parentNode,
activePanel,
var activePanel,
panelIdMatch = /#(.*)$/.exec(e.target.href),
tabPanels;
while ( ! i.className || -1 == i.className.indexOf('inside') ) {
i = i.parentNode;
}
$('.tabs-panel', i).each(function() {
tabPanels,
wrapper = getParentWrapper(e.target, 'inside'),
inputs = wrapper ? wrapper.getElementsByTagName('input') : [],
i = inputs.length;
// upon changing tabs, we want to uncheck all checkboxes
while( i-- )
inputs[i].checked = false;
$('.tabs-panel', wrapper).each(function() {
if ( this.className )
this.className = this.className.replace('tabs-panel-active', 'tabs-panel-inactive');
});
$('.tabs', i).each(function() {
$('.tabs', wrapper).each(function() {
this.className = this.className.replace('tabs', '');
});
@ -396,7 +408,7 @@ var WPNavMenuHandler = function () {
if ( that != currentDropzone || ( ! activeHovering && that.className && -1 != that.className.indexOf('sortable-placeholder') ) ) {
that.className = that.className.replace(/sortable-placeholder/g, '');
}
}, 500);
}, 800);
})(dropEl);
},
@ -563,6 +575,7 @@ var WPNavMenuHandler = function () {
if ( ! req )
req = {};
var dropZone,
dummyListItem = document.getElementById(menuList.id + '-dummy-list-item'),
i,
listElements,
wrap = document.createElement('ul');
@ -572,9 +585,14 @@ var WPNavMenuHandler = function () {
i = listElements.length;
while ( i-- ) {
this.setupListItemDragAndDrop(listElements[i]);
menuList.appendChild(listElements[i]);
if ( dummyListItem )
menuList.insertBefore(listElements[i], dummyListItem);
else
menuList.appendChild(listElements[i]);
}
this.recalculateSortOrder(menuList);
/* set custom link form back to defaults */
if ( customLinkNameInput && customLinkURLInput ) {
customLinkNameInput.value = customLinkNameDefault;

File diff suppressed because one or more lines are too long

View File

@ -169,6 +169,7 @@ add_filter( 'the_posts', '_close_comments_for_old_posts' );
add_filter( 'comments_open', '_close_comments_for_old_post', 10, 2 );
add_filter( 'pings_open', '_close_comments_for_old_post', 10, 2 );
add_filter( 'editable_slug', 'urldecode' );
add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object' );
// Atom SSL support
add_filter( 'atom_service_url','atom_service_url_filter' );

View File

@ -132,10 +132,12 @@ class Walker_Nav_Menu_Checklist extends Walker_Nav_Menu {
* @param object $args
*/
function start_el(&$output, $item, $depth, $args) {
static $_placeholder;
$_placeholder = 0 > $_placeholder ? $_placeholder - 1 : -1;
$possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_placeholder;
global $_nav_menu_placeholder;
$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1;
$possible_object_id = isset( $item->post_type ) && 'nav_menu_item' == $item->post_type ? $item->object_id : $_nav_menu_placeholder;
$possible_db_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->ID : 0;
$possible_parent_id = ( ! empty( $item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $item->post_parent : 0;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
@ -147,7 +149,7 @@ class Walker_Nav_Menu_Checklist extends Walker_Nav_Menu {
// Menu item hidden fields
$output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';
$output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="'. esc_attr( $item->object ) .'" />';
$output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. esc_attr( $item->post_parent ) .'" />';
$output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="'. $possible_parent_id .'" />';
$output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="'. esc_attr( $item->type ) .'" />';
$output .= '<input type="hidden" class="menu-item-append" name="menu-item[' . $possible_object_id . '][menu-item-append]" value="'. esc_attr( $item->append ) .'" />';
$output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="'. esc_attr( $item->title ) .'" />';

View File

@ -50,7 +50,12 @@ function is_nav_menu( $menu ) {
$menu_obj = wp_get_nav_menu_object( $menu );
if ( $menu_obj && ! is_wp_error( $menu_obj ) && ! empty( $menu_obj->term_id ) )
if (
$menu_obj &&
! is_wp_error( $menu_obj ) &&
! empty( $menu_obj->taxonomy ) &&
'nav_menu' == $menu_obj->taxonomy
)
return true;
return false;
@ -143,7 +148,7 @@ function wp_delete_nav_menu( $menu ) {
*
* @param int $menu_id The ID of the menu
* @param array $menu_data The array of menu data.
* @return int The menu's ID.
* @return int|error object The menu's ID or WP_Error object.
*/
function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
$menu_id = (int) $menu_id;
@ -151,11 +156,13 @@ function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
$_menu = wp_get_nav_menu_object( $menu_id );
// menu doesn't already exist
if ( ! $_menu || is_wp_error( $_menu ) ) {
if ( ! $_menu || is_wp_error( $_menu ) )
$_menu = wp_create_nav_menu( $menu_data['menu-name'] );
}
if ( $_menu && isset( $_menu->term_id ) && ! is_wp_error( $_menu ) ) {
if ( is_wp_error( $_menu ) )
return $_menu;
if ( $_menu && isset( $_menu->term_id ) ) {
$args = array(
'description' => ( isset( $menu_data['description'] ) ? $menu_data['description'] : '' ),
'name' => ( isset( $menu_data['menu-name'] ) ? $menu_data['menu-name'] : '' ),
@ -167,9 +174,10 @@ function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
$update_response = wp_update_term( $menu_id, 'nav_menu', $args );
if ( ! is_wp_error( $update_response ) ) {
if ( ! is_wp_error( $update_response ) )
return $menu_id;
}
else
return $update_response;
} else {
return 0;
}
@ -237,6 +245,32 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
}
}
if ( 'custom' != $args['menu-item-type'] ) {
/* if non-custom menu item, then:
* use original object's URL
* blank default title to sync with original object's
*/
$args['menu-item-url'] = '';
$original_title = '';
if ( 'taxonomy' == $args['menu-item-type'] ) {
$original_title = get_term_field( 'name', $args['menu-item-object-id'], $args['menu-item-object'], 'raw' );
} elseif ( 'post_type' == $args['menu-item-type'] ) {
$original_object = get_post( $args['menu-item-object-id'] );
$original_title = $original_object->post_title;
}
if ( empty( $args['menu-item-title'] ) || $args['menu-item-title'] == $original_title ) {
$args['menu-item-title'] = '';
// hack to get wp to create a post object when too many properties are empty
if ( empty( $args['menu-item-description'] ) ) {
$args['menu-item-description'] = ' ';
}
}
}
// Populate the menu item object
$post = array(
'menu_order' => $args['menu-item-position'],
@ -363,6 +397,12 @@ function wp_get_nav_menu_items( $menu, $args = array() ) {
$items = get_posts( $args );
if ( is_wp_error( $items ) || ! is_array( $items ) ) {
return false;
}
$items = array_map( 'wp_setup_nav_menu_item', $items );
if ( ARRAY_A == $args['output'] ) {
$GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
usort($items, '_sort_nav_menu_items');
@ -410,18 +450,25 @@ function wp_setup_nav_menu_item( $menu_item ) {
$object = get_post_type_object( $menu_item->object );
$menu_item->append = $object->singular_label;
$menu_item->url = get_permalink( $menu_item->object_id );
$original_object = get_post( $menu_item->object_id );
$original_title = $original_object->post_title;
$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
} elseif ( 'taxonomy' == $menu_item->type ) {
$object = get_taxonomy( $menu_item->object );
$menu_item->append = $object->singular_label;
$menu_item->url = get_term_link( (int) $menu_item->object_id, $menu_item->object );
$original_title = get_term_field( 'name', $menu_item->object_id, $menu_item->object, 'raw' );
$menu_item->title = '' == $menu_item->post_title ? $original_title : $menu_item->post_title;
} else {
$menu_item->append = __('Custom');
$menu_item->title = $menu_item->post_title;
$menu_item->url = get_post_meta( $menu_item->ID, '_menu_item_url', true );
}
$menu_item->title = $menu_item->post_title;
$menu_item->target = get_post_meta( $menu_item->ID, '_menu_item_target', true );
$menu_item->attr_title = strip_tags( $menu_item->post_excerpt );

View File

@ -393,7 +393,7 @@ function wp_default_scripts( &$scripts ) {
) );
// Custom Navigation
$scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100426' );
$scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100428' );
$scripts->localize( 'nav-menu', 'navMenuL10n', array(
'custom' => _x('Custom', 'menu nav item type'),
'thickbox' => _x('Edit Menu Item', 'Thickbox Title'),