首先感谢万能的谷歌,以及代码作者;
原项目地址:https://github.com/ineagu/wp-menu-item-custom-fields
其实这个需求已经有现成的插件可以做了,不过作为主题开发者当然是希望一些功能尽量的轻便,同时能够继承到主题里;
不废话直接上代码:
第一步: 在主题目录内新建一个目录,这个自定义就OK;
第二步: 新建三个PHP 文件,分别为:
menu-item-custom-fields.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php if ( ! class_exists( 'Menu_Item_Custom_Fields' ) ) : /** * Menu Item Custom Fields Loader */ class Menu_Item_Custom_Fields { /** * Add filter * * @wp_hook action wp_loaded */ public static function load() { add_filter( 'wp_edit_nav_menu_walker', array( __CLASS__, '_filter_walker' ), 99 ); } /** * Replace default menu editor walker with ours * * We don't actually replace the default walker. We're still using it and * only injecting some HTMLs. * * @since 0.1.0 * @access private * @wp_hook filter wp_edit_nav_menu_walker * @param string $walker Walker class name * @return string Walker class name */ public static function _filter_walker( $walker ) { $walker = 'Menu_Item_Custom_Fields_Walker'; if ( ! class_exists( $walker ) ) { require_once dirname( __FILE__ ) . '/walker-nav-menu-edit.php'; } return $walker; } } add_action( 'wp_loaded', array( 'Menu_Item_Custom_Fields', 'load' ), 9 ); endif; // class_exists( 'Menu_Item_Custom_Fields' ) |
walker-nav-menu-edit.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<?php class Menu_Item_Custom_Fields_Walker extends Walker_Nav_Menu_Edit { /** * Start the element output. * * We're injecting our custom fields after the div.submitbox * * @see Walker_Nav_Menu::start_el() * @since 0.1.0 * @since 0.2.0 Update regex pattern to support WordPress 4.7's markup. * * @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 array $args Menu item args. * @param int $id Nav menu ID. */ function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { $item_output = ''; parent::start_el( $item_output, $item, $depth, $args, $id ); $output .= preg_replace( // NOTE: Check this regex from time to time! '/(?=<(fieldset|p)[^>]+class="[^"]*field-move)/', $this->get_fields( $item, $depth, $args ), $item_output ); } /** * Get custom fields * * @access protected * @since 0.1.0 * @uses add_action() Calls 'menu_item_custom_fields' hook * * @param object $item Menu item data object. * @param int $depth Depth of menu item. Used for padding. * @param array $args Menu item args. * @param int $id Nav menu ID. * * @return string Form fields */ protected function get_fields( $item, $depth, $args = array(), $id = 0 ) { ob_start(); /** * Get menu item custom fields from plugins/themes * * @since 0.1.0 * @since 1.0.0 Pass correct parameters. * * @param int $item_id Menu item ID. * @param object $item Menu item data object. * @param int $depth Depth of menu item. Used for padding. * @param array $args Menu item args. * @param int $id Nav menu ID. * * @return string Custom fields HTML. */ do_action( 'wp_nav_menu_item_custom_fields', $item->ID, $item, $depth, $args, $id ); return ob_get_clean(); } } |
wb_menu-item-custom-fields.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<?php //自定义菜单项目 class Menu_Item_Custom_Fields_Example { protected static $fields = array(); public static function init() { add_action( 'wp_nav_menu_item_custom_fields', array( __CLASS__, '_fields' ), 10, 4 ); add_action( 'wp_update_nav_menu_item', array( __CLASS__, '_save' ), 10, 3 ); add_filter( 'manage_nav-menus_columns', array( __CLASS__, '_columns' ), 99 ); self::$fields = array( //这里的数组定义要设置的项目 'field_1' => '自定义1', 'field_2' => '自定义2', ); } public static function _save( $menu_id, $menu_item_db_id, $menu_item_args ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { return; } check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' ); foreach ( self::$fields as $_key => $label ) { $key = sprintf( 'menu-item-%s', $_key ); // Sanitize if ( ! empty( $_POST[ $key ][ $menu_item_db_id ] ) ) { // Do some checks here... $value = $_POST[ $key ][ $menu_item_db_id ]; } else { $value = null; } // Update if ( ! is_null( $value ) ) { update_post_meta( $menu_item_db_id, $key, $value ); } else { delete_post_meta( $menu_item_db_id, $key ); } } } public static function _fields( $id, $item, $depth, $args ) { foreach ( self::$fields as $_key => $label ) : $key = sprintf( 'menu-item-%s', $_key ); $id = sprintf( 'edit-%s-%s', $key, $item->ID ); $name = sprintf( '%s[%s]', $key, $item->ID ); $value = get_post_meta( $item->ID, $key, true ); $class = sprintf( 'field-%s', $_key ); ?> <p class="description description-wide <?php echo esc_attr( $class ) ?>"> <?php printf( '<label for="%1$s">%2$s<br /><input type="text" id="%1$s" class="widefat %1$s" name="%3$s" value="%4$s" /></label>', esc_attr( $id ), $label, esc_attr( $name ), esc_attr( $value ) ) ?> </p> <?php endforeach; } public static function _columns( $columns ) { $columns = array_merge( $columns, self::$fields ); return $columns; } } Menu_Item_Custom_Fields_Example::init(); |
第三步: 在主题函数文件functions.php内引入后两个文件
1 2 |
require_once dirname( __FILE__ ) . '/your dir/menu-item-custom-fields.php'; require_once dirname( __FILE__ ) . '/your dir/wb_menu-item-custom-fields.php'; |
修改第三个文件内的相应代码即可实现自定义选项了。