You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:07:46