如何在不将其添加到菜单的情况下添加 WordPress 管理页面?

How do you add a WordPress admin page without adding it to the menu?

我正在构建一个 WordPress 插件,我希望有一个无法通过子菜单访问的编辑项目页面(因为这样就不会指定项目)。

此资源 (http://codex.wordpress.org/Adding_Administration_Menus) 展示了如何将管理页面与功能相关联,而不是在不将其添加为菜单项的情况下如何做到这一点。

这样可以吗?

谢谢!


最佳解决方案在这里 http://wordpress.org/support/topic/add-backend-page-without-menu-item

use add_submenu_page with parent slug = null


我终于找到了一种方法,它不是丑陋的 hack,不需要 JS 突出显示所需的菜单项(和子菜单项),并且适用于插件注册的常规菜单(@Josh \\ 的答案仅适用于自定义帖子类型)。

基本上,您只需要正常注册您的子菜单,然后连接到 'submenu_file' 过滤器以取消注册它,并且还可以选择设置另一个子菜单项以突出显示。

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
function so3902760_wp_admin_menu() {

    // Register the parent menu.
    add_menu_page(
        __( 'Parent title', 'textdomain' )
        , __( 'Parent', 'textdomain' )
        , 'manage_options'
        , 'my_parent_slug'
        , 'display_my_menu'
    );

    // Register the hidden submenu.
    add_submenu_page(
        'my_parent_slug' // Use the parent slug as usual.
        , __( 'Page title', 'textdomain' )
        , ''
        , 'manage_options'
        , 'my_hidden_submenu'
        , 'display_my_submenu'
    );
}
add_action( 'admin_menu', 'so3902760_wp_admin_menu' );

function so3902760_wp_admin_submenu_filter( $submenu_file ) {

    global $plugin_page;

    $hidden_submenus = array(
        'my_hidden_submenu' => true,
    );

    // Select another submenu item to highlight (optional).
    if ( $plugin_page && isset( $hidden_submenus[ $plugin_page ] ) ) {
        $submenu_file = 'submenu_to_highlight';
    }

    // Hide the submenu.
    foreach ( $hidden_submenus as $submenu => $unused ) {
        remove_submenu_page( 'my_parent_slug', $submenu );
    }

    return $submenu_file;
}
add_filter( 'submenu_file', 'so3902760_wp_admin_submenu_filter' );


是的,这可以做到(嗯,从技术上讲,这更像是注册整个东西,然后稍后删除菜单项),但检查 超全局表示用户希望编辑特定项目。

例如,您可以有一个列出要编辑的项目的页面,然后单击"编辑"只会将项目的 ID 添加到当前 URL(查询字符串)。

在显示此页面的函数中,如果定义了 ID,则给他们编辑该项目的页面。

否则,给他们列表视图。帖子、页面和其他自定义帖子类型就是这样做的。


add_submenu_page with parent slug = null

add_submenu_page with menu title = null


Note: This solution doesn't automatically set the current menu and submenu item. If you want to highlight a particular menu as current when the hidden page is viewed, see my other answer.

从我面前的答案中,您可以看到有很多方法可以做到这一点。但是,我认为还有另一种方法可能是最好的。

根据 $_GET 查询变量的值以不同方式加载页面是一种选择,但它可能不是某些人想要的。

关于add_submenu_page()的建议都在正确的Rails上,但是之前的每一个建议都有问题。将 $menu_title 设置为 null 不会阻止显示菜单项,它只是使链接没有任何文本。该链接仍然在菜单中占据了一些空间,所以看起来很有趣。将 $parent_slug 设置为 null 没有这个问题,但我注意到页面的 HTML title 不显示 $page_title 文本。

我的解决方案是将 $parent_slug 设置为一个虚假的菜单项,例如 'i_dont_exist'。菜单项不会显示,并且在查看管理屏幕时会正确填写页面标题。

1
2
3
4
5
6
7
8
add_submenu_page(
    '_doesnt_exist'
    ,__( 'Page title', 'textdomain' )
    ,''
    ,'manage_options'
    ,'menu_slug'
    ,'display_my_menu'
);


使用此代码创建新页面而不添加菜单

1
2
3
4
5
6
7
8
9
10
11
add_action( 'admin_menu', 'register_newpage' );

function register_newpage(){
    add_menu_page($appname, $appname, 'administrator','custompage', 'custom');
    remove_menu_page('custom');
}

function custom()
{
echo"hai";
}


是的。很可能无法通过子菜单访问页面,甚至是 WP 管理面板中的主菜单。请参阅下面的代码片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function myplugin_render_edit_page() {
    // Code contains the UI for edit page.
}

/**
 * Manage menu items and pages.
 */
function myplugin_register_admin_page() {
    global $_registered_pages;

    $menu_slug = plugin_basename('myplugin.php');
    $hookname = get_plugin_page_hookname($menu_slug,'');
    if (!empty($hookname)) {
        add_action($hookname, 'myplugin_render_edit_page');
    }
    $_registered_pages[$hookname] = true;
}
add_action('admin_menu', 'myplugin_register_admin_page');

希望这会有所帮助。


创建子菜单页面和父 slug 将其留空,如下所示:

1
2
3
4
5
6
7
8
9
10
11
// Create page were you can add new users.
    public function add_create_user_menu() {
        add_submenu_page(
            '',
            'Create User',
            'Create User',
            'manage_options',
            'create-user',
            array( $this, 'add_create_user_page' )
        );
    }

你可以这样访问它:

1
Add New

使用带有 NULL 父级的 add_submenu_page 绝对有效,但是如果您想保持与特定菜单关联的非链接页面(例如自定义帖子类型菜单),您必须使用 @Boopathi\\'s 的变体答案:

1
2
3
4
5
6
7
function my_hidden_submenu_page(){
    //add the submenu page the usual way
    add_submenu_page('edit.php?post_type=custom-type', 'My Page Title', 'My Page Title', 'manage_options', 'my-page-slug', 'my_page_callback');
    //then remove it
    remove_submenu_page('edit.php?post_type=custom-type','my-page-slug');
}
add_action('admin_menu', 'my_hidden_submenu_page');

看起来这两个动作会相互抵消,但是 remove_submenu_page 并没有取消注册回调函数;它只是删除了链接。

这样,当有人查看您的非链接页面时,正确的导航菜单(本示例中为我们的自定义帖子类型菜单)仍将显示为活动状态。


我已经尝试了这里的所有建议,但每个建议都有各种相关的问题。

add_submenu_page 的 WordPress 代码现在给出了正确的答案,即使用 options.php 作为你的父 slug。我尝试了使用虚构名称的技巧,但这会导致权限错误,同样在不同位置使用 null 会导致菜单文本简单丢失(但仍可单击)或浏览器标题丢失。

使用 options.php 有效,我没有看到任何问题。


看来这个需求对现在的版本仍然有效。
我正在使用 WordPress 5.3.2 并使用以下方法从 submenu.

中删除父命名菜单

1
2
3
4
5
6
7
8
9
10
11
12
add_action( 'admin_menu', 'submenus' );

function submenus()
    {
        global $submenu;

        $parent_slug = 'parent_slug_name';

        // remove parent named menu from submenu because it is always the first one in the submenu array, so the offset is 0 and remove just 1
        array_splice( $submenu[$parent_slug], 0, 1 ); // with reindex
        // or unset( $submenu[$parent_slug][0] ); // without reindex
    }

希望它能帮助其他想要实现相同目标的人。

  • 关于 php array_splice()
  • 此方法可以在 WP 函数 remove_submenu_page() 的源代码中找到,该函数自 WP 3.1.0 起可用

编辑/添加

除了子菜单,父菜单也可以类似的方式更新。
对于父菜单,全局变量是 $menu
参考示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
add_action( 'admin_menu', array( $this, 'modify_menu_title' ) );

function modify_menu_title() {
    global $menu;

    $page = 'some-page-slug';
    $new_menu_title = 'New Title Name';
    foreach( $menu as $key => $value ) {
        if( $menu[$key][2] === $page ) {
            $menu[$key][0] = $new_menu_title;
        }
    }
}

我发现仅添加 null 作为子菜单项的父项的问题之一是,如果您当前正在查看该特定页面,子菜单本身将不会显示(至少它没有对我来说(连同未显示的页面标题)。

我所做的是在菜单标题内添加一个空的span元素,并使用jquery遍历父元素并隐藏它。


我发现你可以通过重复使用插入 ID 来做到这一点,如下所示:

1
2
3
add_menu_page( 'User AS Packages', 'User AS', 'manage_options', 'myplugin/editaspackages.php', 'UserASPackages', '', 8);
add_menu_page( 'User ARP Packages', 'User ARP', 'manage_options', 'myplugin/editarppackages.php', 'UserARPPackages', '', 8);
add_menu_page( 'AS Packages', 'AS Packages', 'manage_options', 'myplugin/ars-s2.php', 'ARPPackages', '', 8);

最后 3 个使用位置 8,最后一个覆盖前面的两个,所以前面的两个不出现。