此文章,转载 ashu.com 的,很实用,但目前我用的后台框架可以更方便的给菜单添加字段,所以暂时存放,等日后再来研究。
1、wordpress的文章有个自定义字段,而且在本工作室前面的教程中也有关于添加自定义字段的教程和类文件。
2、wordpress的菜单也是“某一个文章类型”,类型名为nav_menu_item,可以参考:wordpress进阶教程(一):wordpress文章类型,每一个菜单项是“一篇文章”,每一个菜单就是“一个分类”,分类法为nav_menu。
菜单在后台的显示代码在 wp-admin/includes/nav-menu.php 文件中,在类 Walker_Nav_Menu_Edit 很容易在里面找到后台菜单项的显示代码,但是寻找后发现,代码中并没有提供过滤器或者动作钩子。
添加代码
将 wp-admin/includes/nav-menu.php 文件中 Walker_Nav_Menu_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;
?>
修改默认的 walker 类为新类
//该过滤器位于nav-menu.php
add_filter( 'wp_edit_nav_menu_walker', 'custom_nav_edit_walker',10,2 );
function custom_nav_edit_walker($walker,$menu_id) {
return 'Walker_Nav_Menu_Edit_Custom';//新类名
}
数据的保存和更新
//注意下面代码中的字符 ashuwp
add_action('wp_update_nav_menu_item', 'custom_nav_update',10, 3);
function custom_nav_update($menu_id, $menu_item_db_id, $args ) {
if ( is_array($_REQUEST['menu-item-ashuwp']) ) {
$custom_value = $_REQUEST['menu-item-ashuwp'][$menu_item_db_id];
update_post_meta( $menu_item_db_id, '_menu_item_ashuwp', $custom_value );
}
}
add_filter( 'wp_setup_nav_menu_item','custom_nav_item' );
function custom_nav_item($menu_item) {
$menu_item->ashuwp = get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );
return $menu_item;
}
实际调用
对于文章字段的调用,我们通过 get_post_meta函数来获取文章的字段,菜单项也一样,对每个菜单,我们在知道他的“文章ID”后,也通过get_post_meta函数来调用
//对应于上面的代码,获取方法 get_post_meta( $menu_item->ID, '_menu_item_ashuwp', true );