WordPress自定义后台菜单:如何创建子菜单的子菜单?
WordPress后台实现带三级子菜单的自定义菜单(含外部链接)
问题背景
需在WordPress后台创建三级嵌套的自定义菜单:顶级菜单「Content」下的一级子菜单(如「...create CPT」),下方还要包含「..item 1」等子子菜单。目前已实现顶级菜单和一级子菜单,但无法添加三级子菜单,原实现代码如下:
add_action('admin_menu', 'admin_menu_add_external_links_as_submenu'); add_action( 'admin_head', 'admin_menu_add_external_links_as_submenu_jquery' ); function admin_menu_add_external_links_as_submenu() { global $submenu; $menu_slug = "externallink"; // 菜单标识 $menu_pos = 2; // 菜单显示位置 // 创建顶级菜单 add_menu_page( 'external_link', 'Content', 'read', $menu_slug, '', '', $menu_pos); // 添加一级子菜单(外部链接) $submenu[$menu_slug][] = array('<div id="newtab1">...create CPT</div>', 'manage_options', 'https://wpsimplehacks.com/how-to-create-custom-post-type-in-wordpress-without-a-plugin-within-couple-of-minutes/'); $submenu[$menu_slug][] = array('<div id="newtab2">...use Blocks</div>', 'manage_options', 'https://wpsimplehacks.com/how-to-use-blocksy-content-blocks-hooks-full-tutorial/'); $submenu[$menu_slug][] = array('<div id="newtab3">...get discounts</div>', 'manage_options', 'https://wpsimplehacks.com/start-here/'); function admin_menu_add_external_links_as_submenu_jquery() { ?> <script type="text/javascript"> jQuery(document).ready( function($) { $('#newtab1').parent().attr('target','_blank'); $('#newtab2').parent().attr('target','_blank'); $('#newtab3').parent().attr('target','_blank'); }); </script> <?php } }
解决方案
WordPress原生支持通过add_submenu_page创建三级菜单,核心思路是:先为一级子菜单创建空回调的父容器,再为该容器添加三级子菜单,最后通过JS替换外部链接并修复显示样式。
完整实现代码
add_action('admin_menu', 'custom_admin_menu_with_three_levels'); add_action('admin_head', 'custom_menu_external_links_and_styles'); function custom_admin_menu_with_three_levels() { // 1. 创建顶级菜单 $top_menu_slug = 'custom-content-menu'; add_menu_page( '自定义内容菜单', 'Content', 'read', $top_menu_slug, '', // 空回调,仅作为菜单容器 '', 2 // 菜单显示位置 ); // 2. 创建一级子菜单(作为三级菜单的父容器,空回调) $level1_parent_slug = 'create-cpt-parent'; add_submenu_page( $top_menu_slug, '创建自定义文章类型', '...create CPT', 'manage_options', $level1_parent_slug, '__return_empty_string' // 空回调,仅作容器 ); // 3. 为一级父菜单添加三级子菜单 global $submenu; $submenu[$level1_parent_slug][] = array('..item 1', 'manage_options', 'https://example.com/item1'); $submenu[$level1_parent_slug][] = array('..item 2', 'manage_options', 'https://example.com/item2'); $submenu[$level1_parent_slug][] = array('..item 3', 'manage_options', 'https://example.com/item3'); // 4. 添加其他一级子菜单(临时slug,后续用JS替换为外部链接) add_submenu_page( $top_menu_slug, '使用区块', '...use Blocks', 'manage_options', 'use-blocks-temp' ); add_submenu_page( $top_menu_slug, '获取折扣', '...get discounts', 'manage_options', 'get-discounts-temp' ); } function custom_menu_external_links_and_styles() { ?> <style type="text/css"> /* 修复三级菜单的显示样式 */ #adminmenu .wp-submenu .wp-submenu { left: 100%; top: 0; margin-top: -1px; } #adminmenu li.wp-has-submenu.wp-has-current-submenu.wp-menu-open li.wp-has-submenu:hover > .wp-submenu { display: block; } </style> <script type="text/javascript"> jQuery(document).ready(function($) { // 替换一级子菜单的外部链接 $('a[href="admin.php?page=use-blocks-temp"]').attr({ 'href': 'https://example.com/use-blocks', 'target': '_blank' }); $('a[href="admin.php?page=get-discounts-temp"]').attr({ 'href': 'https://example.com/get-discounts', 'target': '_blank' }); // 替换三级子菜单的外部链接 $('a[href="admin.php?page=https://example.com/item1"]').attr({ 'href': 'https://example.com/item1', 'target': '_blank' }); $('a[href="admin.php?page=https://example.com/item2"]').attr({ 'href': 'https://example.com/item2', 'target': '_blank' }); $('a[href="admin.php?page=https://example.com/item3"]').attr({ 'href': 'https://example.com/item3', 'target': '_blank' }); // 为一级父菜单添加hover展开三级菜单的事件 $('#adminmenu li a[href="admin.php?page=create-cpt-parent"]').parent().hover(function() { $(this).find('.wp-submenu').show(); }, function() { $(this).find('.wp-submenu').hide(); }); }); </script> <?php }
关键说明
- 顶级菜单:用
add_menu_page创建空回调的顶级菜单,仅作为容器。 - 一级父菜单:通过
add_submenu_page创建空回调的一级子菜单,作为三级菜单的父容器,其slug是添加三级菜单的标识。 - 三级菜单:通过全局
$submenu数组,以一级父菜单的slug为键,添加三级子菜单项。 - 外部链接处理:通过JS将临时slug对应的菜单链接替换为真实外部地址,并设置
target="_blank"实现新标签打开。 - 样式修复:添加CSS确保三级菜单在hover时能正确显示在一级子菜单右侧。
注意事项
- 将代码中所有
https://example.com替换为实际需要的外部链接。 - 权限参数(如
manage_options)可根据需求调整,确保对应角色能看到菜单。 - 菜单位置
2可根据后台布局调整,避免与默认菜单冲突。
内容的提问来源于stack exchange,提问作者John Adams
相关产品推荐
相关产品推荐

