我们知道1、wordpress的文章有个自定义字段,而且在本工作室前面的教程中也有关于添加自定义字段的教程和类文件。2、wordpress的菜单也是“某一个文章类型”,类型名为nav_menu_item,可以参考:wordpress进阶教程(一):wordpress文章类型,每一个菜单项是“一篇文章”,每一个菜单就是“一个分类”,分类法为nav_menu。
申明:本文中的代码搜集自互联网。
那么在wordpress中,菜单也可以添加自定义字段。
菜单在后台的显示代码在wp-admin/includes/nav-menu.php文件中,在类Walker_Nav_Menu_Edit很容易在里面找到后台菜单项的显示代码,但是寻找后发现,代码中并没有提供过滤器或者动作钩子。
方法:
一、将wp-admin/includes/nav-menu.php文件中Walker_Nav_Mnu_Edit类复制一份粘贴到主题functions.php文件中,更改类名,然后在里面添加相应的代码。如下:
class Walker_Nav_Menu_Edit_Custom extends Walker_Nav_Menu {
/**
* @see Walker_Nav_Menu::start_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function start_lvl(&$output) {}
/**
* @see Walker_Nav_Menu::end_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function end_lvl(&$output) {
}
/**
* @see Walker::start_el()
* @since 3.0.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param object $args
*/
function start_el(&$output, $item, $depth, $args) {
global $_wp_nav_menu_max_depth;
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
ob_start();
$item_id = esc_attr( $item->ID );
$removed_args = array(
'action',
'customlink-tab',
'edit-menu-item',
'menu-item',
'page-tab',
'_wpnonce',
);
$original_title = '';
if ( 'taxonomy' == $item->type ) {
$original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
if ( is_wp_error( $original_title ) )
$original_title = false;
} elseif ( 'post_type' == $item->type ) {
$original_object = get_post( $item->object_id );
$original_title = $original_object->post_title;
}
$classes = array(
'menu-item menu-item-depth-' . $depth,
'menu-item-' . esc_attr( $item->object ),
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'),
);
$title = $item->title;
if ( ! empty( $item->_invalid ) ) {
$classes[] = 'menu-item-invalid';
/* translators: %s: title of menu item which is invalid */
$title = sprintf( __( '%s (Invalid)' ), $item->title );
} elseif ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
$classes[] = 'pending';
/* translators: %s: title of menu item in draft status */
$title = sprintf( __('%s (Pending)'), $item->title );
}
$title = empty( $item->label ) ? $title : $item->label;
?>
" class="">
type_label ); ?>
'move-up-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-up">">↑
|
'move-down-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-down">">↓
" title="" href="">
">
type ) : ?>
">
" class="widefat code edit-menu-item-url" name="menu-item-url[]" value="url ); ?>" />
">
" class="widefat edit-menu-item-title" name="menu-item-title[]" value="title ); ?>" />
">
" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[]" value="post_excerpt ); ?>" />
">
" value="_blank" name="menu-item-target[]"target, '_blank' ); ?> />
">
" class="widefat code edit-menu-item-classes" name="menu-item-classes[]" value="classes ) ); ?>" />
">
" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[]" value="xfn ); ?>" />
">
" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[]">description ); // textarea_escaped ?>
">阿树工作室
" class="widefat code edit-menu-item-ashuwp" name="menu-item-ashuwp[]" value="ashuwp ); ?>" />
type && $original_title !== false ) : ?>
url ) . '">' . esc_html( $original_title ) . '' ); ?>
" href=" 'delete-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'delete-menu_item_' . $item_id
); ?>"> | " href=" $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) ) );
?>#menu-item-settings-">
]" value="" />
]" value="object_id ); ?>" />
]" value="object ); ?>" />
]" value="menu_item_parent ); ?>" />
]" value="menu_order ); ?>" />
]" value="type ); ?>" />
ashuwp = get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
return $menu_item;
}
//对应于上面的代码,获取方法
get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
二、修改默认的walker类为新类:
class Walker_Nav_Menu_Edit_Custom extends Walker_Nav_Menu {
/**
* @see Walker_Nav_Menu::start_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function start_lvl(&$output) {}
/**
* @see Walker_Nav_Menu::end_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function end_lvl(&$output) {
}
/**
* @see Walker::start_el()
* @since 3.0.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param object $args
*/
function start_el(&$output, $item, $depth, $args) {
global $_wp_nav_menu_max_depth;
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
ob_start();
$item_id = esc_attr( $item->ID );
$removed_args = array(
'action',
'customlink-tab',
'edit-menu-item',
'menu-item',
'page-tab',
'_wpnonce',
);
$original_title = '';
if ( 'taxonomy' == $item->type ) {
$original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
if ( is_wp_error( $original_title ) )
$original_title = false;
} elseif ( 'post_type' == $item->type ) {
$original_object = get_post( $item->object_id );
$original_title = $original_object->post_title;
}
$classes = array(
'menu-item menu-item-depth-' . $depth,
'menu-item-' . esc_attr( $item->object ),
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'),
);
$title = $item->title;
if ( ! empty( $item->_invalid ) ) {
$classes[] = 'menu-item-invalid';
/* translators: %s: title of menu item which is invalid */
$title = sprintf( __( '%s (Invalid)' ), $item->title );
} elseif ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
$classes[] = 'pending';
/* translators: %s: title of menu item in draft status */
$title = sprintf( __('%s (Pending)'), $item->title );
}
$title = empty( $item->label ) ? $title : $item->label;
?>
" class="">
type_label ); ?>
'move-up-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-up">">↑
|
'move-down-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-down">">↓
" title="" href="">
">
type ) : ?>
">
" class="widefat code edit-menu-item-url" name="menu-item-url[]" value="url ); ?>" />
">
" class="widefat edit-menu-item-title" name="menu-item-title[]" value="title ); ?>" />
">
" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[]" value="post_excerpt ); ?>" />
">
" value="_blank" name="menu-item-target[]"target, '_blank' ); ?> />
">
" class="widefat code edit-menu-item-classes" name="menu-item-classes[]" value="classes ) ); ?>" />
">
" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[]" value="xfn ); ?>" />
">
" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[]">description ); // textarea_escaped ?>
">阿树工作室
" class="widefat code edit-menu-item-ashuwp" name="menu-item-ashuwp[]" value="ashuwp ); ?>" />
type && $original_title !== false ) : ?>
url ) . '">' . esc_html( $original_title ) . '' ); ?>
" href=" 'delete-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'delete-menu_item_' . $item_id
); ?>"> | " href=" $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) ) );
?>#menu-item-settings-">
]" value="" />
]" value="object_id ); ?>" />
]" value="object ); ?>" />
]" value="menu_item_parent ); ?>" />
]" value="menu_order ); ?>" />
]" value="type ); ?>" />
ashuwp = get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
return $menu_item;
}
//对应于上面的代码,获取方法
get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
注意上面新类代码中有一段新添加的代码,以及类名修改为Walker_Nav_Menu_Edit_Custom,至此新类就启用了。
三、数据的保存和更新:
class Walker_Nav_Menu_Edit_Custom extends Walker_Nav_Menu {
/**
* @see Walker_Nav_Menu::start_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function start_lvl(&$output) {}
/**
* @see Walker_Nav_Menu::end_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function end_lvl(&$output) {
}
/**
* @see Walker::start_el()
* @since 3.0.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param object $args
*/
function start_el(&$output, $item, $depth, $args) {
global $_wp_nav_menu_max_depth;
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
ob_start();
$item_id = esc_attr( $item->ID );
$removed_args = array(
'action',
'customlink-tab',
'edit-menu-item',
'menu-item',
'page-tab',
'_wpnonce',
);
$original_title = '';
if ( 'taxonomy' == $item->type ) {
$original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
if ( is_wp_error( $original_title ) )
$original_title = false;
} elseif ( 'post_type' == $item->type ) {
$original_object = get_post( $item->object_id );
$original_title = $original_object->post_title;
}
$classes = array(
'menu-item menu-item-depth-' . $depth,
'menu-item-' . esc_attr( $item->object ),
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'),
);
$title = $item->title;
if ( ! empty( $item->_invalid ) ) {
$classes[] = 'menu-item-invalid';
/* translators: %s: title of menu item which is invalid */
$title = sprintf( __( '%s (Invalid)' ), $item->title );
} elseif ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
$classes[] = 'pending';
/* translators: %s: title of menu item in draft status */
$title = sprintf( __('%s (Pending)'), $item->title );
}
$title = empty( $item->label ) ? $title : $item->label;
?>
" class="">
type_label ); ?>
'move-up-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-up">">↑
|
'move-down-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-down">">↓
" title="" href="">
">
type ) : ?>
">
" class="widefat code edit-menu-item-url" name="menu-item-url[]" value="url ); ?>" />
">
" class="widefat edit-menu-item-title" name="menu-item-title[]" value="title ); ?>" />
">
" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[]" value="post_excerpt ); ?>" />
">
" value="_blank" name="menu-item-target[]"target, '_blank' ); ?> />
">
" class="widefat code edit-menu-item-classes" name="menu-item-classes[]" value="classes ) ); ?>" />
">
" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[]" value="xfn ); ?>" />
">
" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[]">description ); // textarea_escaped ?>
">阿树工作室
" class="widefat code edit-menu-item-ashuwp" name="menu-item-ashuwp[]" value="ashuwp ); ?>" />
type && $original_title !== false ) : ?>
url ) . '">' . esc_html( $original_title ) . '' ); ?>
" href=" 'delete-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'delete-menu_item_' . $item_id
); ?>"> | " href=" $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) ) );
?>#menu-item-settings-">
]" value="" />
]" value="object_id ); ?>" />
]" value="object ); ?>" />
]" value="menu_item_parent ); ?>" />
]" value="menu_order ); ?>" />
]" value="type ); ?>" />
ashuwp = get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
return $menu_item;
}
//对应于上面的代码,获取方法
get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
效果图:
五、实际调用
对于文章字段的调用,我们通过 get_post_meta函数来获取文章的字段,菜单项也一样,对每个菜单,我们在知道他的“文章ID”后,也通过get_post_meta函数来调用。
class Walker_Nav_Menu_Edit_Custom extends Walker_Nav_Menu {
/**
* @see Walker_Nav_Menu::start_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function start_lvl(&$output) {}
/**
* @see Walker_Nav_Menu::end_lvl()
* @since 3.0.0
*
* @param string $output Passed by reference.
*/
function end_lvl(&$output) {
}
/**
* @see Walker::start_el()
* @since 3.0.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param object $args
*/
function start_el(&$output, $item, $depth, $args) {
global $_wp_nav_menu_max_depth;
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
ob_start();
$item_id = esc_attr( $item->ID );
$removed_args = array(
'action',
'customlink-tab',
'edit-menu-item',
'menu-item',
'page-tab',
'_wpnonce',
);
$original_title = '';
if ( 'taxonomy' == $item->type ) {
$original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
if ( is_wp_error( $original_title ) )
$original_title = false;
} elseif ( 'post_type' == $item->type ) {
$original_object = get_post( $item->object_id );
$original_title = $original_object->post_title;
}
$classes = array(
'menu-item menu-item-depth-' . $depth,
'menu-item-' . esc_attr( $item->object ),
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'),
);
$title = $item->title;
if ( ! empty( $item->_invalid ) ) {
$classes[] = 'menu-item-invalid';
/* translators: %s: title of menu item which is invalid */
$title = sprintf( __( '%s (Invalid)' ), $item->title );
} elseif ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
$classes[] = 'pending';
/* translators: %s: title of menu item in draft status */
$title = sprintf( __('%s (Pending)'), $item->title );
}
$title = empty( $item->label ) ? $title : $item->label;
?>
" class="">
type_label ); ?>
'move-up-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-up">">↑
|
'move-down-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>" class="item-move-down">">↓
" title="" href="">
">
type ) : ?>
">
" class="widefat code edit-menu-item-url" name="menu-item-url[]" value="url ); ?>" />
">
" class="widefat edit-menu-item-title" name="menu-item-title[]" value="title ); ?>" />
">
" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[]" value="post_excerpt ); ?>" />
">
" value="_blank" name="menu-item-target[]"target, '_blank' ); ?> />
">
" class="widefat code edit-menu-item-classes" name="menu-item-classes[]" value="classes ) ); ?>" />
">
" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[]" value="xfn ); ?>" />
">
" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[]">description ); // textarea_escaped ?>
">阿树工作室
" class="widefat code edit-menu-item-ashuwp" name="menu-item-ashuwp[]" value="ashuwp ); ?>" />
type && $original_title !== false ) : ?>
url ) . '">' . esc_html( $original_title ) . '' ); ?>
" href=" 'delete-menu-item',
'menu-item' => $item_id,
),
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
),
'delete-menu_item_' . $item_id
); ?>"> | " href=" $item_id, 'cancel' => time()), remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) ) ) );
?>#menu-item-settings-">
]" value="" />
]" value="object_id ); ?>" />
]" value="object ); ?>" />
]" value="menu_item_parent ); ?>" />
]" value="menu_order ); ?>" />
]" value="type ); ?>" />
ashuwp = get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
return $menu_item;
}
//对应于上面的代码,获取方法
get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );