How do you add a WordPress admin page without addi

2019-01-30 13:53发布

I'm building a WordPress plugin and I'd like to have an edit-item page that can't be reached via the submenu (because then the item wouldn't be specified).

This resource (http://codex.wordpress.org/Adding_Administration_Menus) shows how to associate an admin page with a function, but not how to do so without adding it as a menu item.

Can this be done?

Thanks!

标签: wordpress
12条回答
Ridiculous、
2楼-- · 2019-01-30 14:06

Yes. It is very possible to make a page cannot be reach via submenu, or even the main menu in the WP admin panel. See the code snippet below.

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');

Hopefully, this will help.

查看更多
Luminary・发光体
3楼-- · 2019-01-30 14:06

Using add_submenu_page with a parent of NULL definitely works, however if you want to keep the non-linked page associated with a particular menu (say a custom post type menu), you have to use a variation of @Boopathi's answer:

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');

It looks as though the two actions would cancel each other out, however remove_submenu_page does not unregister the callback function; it merely removes the link.

This way when someone is viewing your non-linked page, the correct navigation menu (our custom post type menu in this example) will still show as active.

查看更多
萌系小妹纸
4楼-- · 2019-01-30 14:14

One of the problems I found with merely adding null as the parent slug for a sub menu item is that if you're currently viewing that specific page the submenu itself won't display (at least it didn't for me (along with the page title not showing).

What I did was add an empty span element inside the menu title and use jquery to traverse the parent elements and hide it.

查看更多
Summer. ? 凉城
5楼-- · 2019-01-30 14:18

I have finally discovered a way to do this that isn't an ugly hack, doesn't require JS to highlight the desired menu item (and submenu item), and works for regular menus registered by plugins (@Josh's answer only works for custom post types).

Essentially, you just need to register your submenu normally, but then hook into the 'submenu_file' filter to deregister it and optionally also set another submenu item to highlight instead.

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' );
查看更多
老娘就宠你
6楼-- · 2019-01-30 14:19

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.

From the answers that come before me, you can see that there are many ways to do this. However, there is another way that I think may be the best.

Loading the page differently based on the value of a $_GET query var is one option, but it may not be what some people are looking for.

The suggestions regarding add_submenu_page() are on the right track, but each of the previous suggestions have problems. Setting $menu_title to null doesn't keep the menu item from being displayed, it just makes it so the link doesn't have any text. The link still takes up some room in the menu though, so it looks funny. Setting the $parent_slug to null doesn't have this problem, but I noticed that the page's HTML title doesn't display the $page_title text.

My solution was to set $parent_slug to a fake menu slug, like 'i_dont_exist'. The menu item won't be displayed, and when viewing the admin screen the page title will be filled out properly.

add_submenu_page(
    '_doesnt_exist'
    ,__( 'Page title', 'textdomain' )
    ,''
    ,'manage_options'
    ,'menu_slug'
    ,'display_my_menu'
);
查看更多
该账号已被封号
7楼-- · 2019-01-30 14:20

Yes, this can be done (well, technically, it would be more like registering the whole thing and then removing the menu item later), but It would just be easiest (I think) to check for parameters in the $_GET super-global to indicate that the user wishes to edit a specific item.

For example, you could have a page that lists items to edit, and clicking 'edit' only adds the item's ID to the current URL(query-string).

In the function that displays this page, if ID is defined, give them the page to edit that item.

Otherwise, give them the list view. That's how posts, pages, and other custom post types do it.

查看更多
登录 后发表回答