I'm trying to add extra pages to my wordpress plugin and link to these pages through links, form forwards etc.

I don't want them to appear in the menu on the left - so add_submenu_page isn't the right approach.

When I try to access the page directly in the link - ie I get a permission error ("You do not have sufficient permissions to access this page.") Also with this approach I am using a direct link to a php page, and not what wordpress seems to want which is a 'slug' or something which internally points to a page/function.

I was wondering how to add a link of the form 'admin.php?page=create_item' and have that forward the request to a function/specific page in my plugin.

Any help would be great :)

  • Just wanted to add putting $_GET's in the main function that runs for my first page is very cluttering. I did implement the plugin this way but when you have 10/15 switches coming off this main function it would be a lot clearer if you could link requests to the correct places.
    – Gorath
    Feb 6, 2016 at 21:32
  • Add_submenu causes WP to set up permissions for that page so it's pretty much the only way. Do you have any admin pages for your plugin? Feb 7, 2016 at 21:53

1 Answer 1


If you need admin pages that don't appear in the menu, use add_submenu_page and set $parent to null. This will create a functional page that doesn't get rendered in the menu.

add_action( 'admin_menu', 'wpd_hidden_plugin_submenu_page' );
function wpd_hidden_plugin_submenu_page() {
        'My Hidden Submenu Page',
        'My Hidden Submenu Page',

Users will need whatever capability you specify to visit those pages.

If you want to create action links that do things outside the context of the admin interface, use the admin_post_ action. You use add_action to hook a handler function to admin_post_ plus the slug of your custom action. Note that there are two hooks- for logged in and not logged in visitors.

// hook your handler function for logged in users
add_action( 'admin_post_my_action', 'wpd_my_action_function' );

//hook your handler function for non logged in users
add_action( 'admin_post_nopriv_my_action', 'wpd_my_action_function' );

function wpd_my_action_function(){
    // WordPress API works in here
    status_header( 200 );

    // do your plugin stuff

    // and always die() at the end to halt execution

To output the URL of the handler script, use admin_url(). Note the action slug my_action is passed in the action form element. This will trigger our hooked function.

<form action="<?php echo admin_url( 'admin-post.php' ); ?>" method="post">
    <input type="hidden" name="action" value="my_action">
    <input type="hidden" name="data" value="some-data">
    <input type="submit" value="Submit">

Adding AJAX action handlers is the same as the admin_post_ action, just the tag name you hook differs, and the URL is admin-ajax.php.

add_action( 'wp_ajax_add_foobar', 'prefix_ajax_add_foobar' );
add_action( 'wp_ajax_nopriv_add_foobar', 'prefix_ajax_add_foobar' );

function prefix_ajax_add_foobar() {
    // Handle request then generate response using WP_Ajax_Response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.