Languages: English • 中文(简体) • Administration Menus 日本語 Русский • (Add your language)
Usually, plugin and theme authors need to provide access to a settings (options) screen so users can customize how the plugin or theme is used. The best way to present the user with such a screen is to create an administration menu item that allows the user to access that settings screen from all the Administration Screens. This article explains how plugin authors can add administration menus and screens. Note: the following information assumes a knowledge of the basics of Writing a Plugin and using the Plugin API of Actions and Filters.
|
|
To add an administration menu, you must do three things:
It is that second step that is often overlooked by new developers. You cannot simply call the menu code described; you must put it inside a function, and then register the function.
Here is a very simple example of the three steps just described. This plugin will add a sub-level menu item under the Settings top-level menu in Administration Screens, and when selected, that menu item will cause a very basic screen to display. Note: this code should be added to a main plugin PHP file or a separate PHP include file.
<?php /** Step 2 (from text above). */ add_action( 'admin_menu', 'my_plugin_menu' ); /** Step 1. */ function my_plugin_menu() { add_options_page( 'My Plugin Options', 'My Plugin', 'manage_options', 'my-unique-identifier', 'my_plugin_options' ); } /** Step 3. */ function my_plugin_options() { if ( !current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); } echo '<div class="wrap">'; echo '<p>Here is where the form would go if I actually had options.</p>'; echo '</div>'; } ?>
In this example, the function my_plugin_menu() adds a new item to the Settings administration menu via the add_options_page() function. Note: more complicated multiple menu items can be added, but that will be described later. Notice the add_action() call in Step 2 that registers the my_plugin_menu() function under the admin_menu hook. Without that add_action() call, a PHP error for undefined function will be thrown when attempting to activate the plugin. Finally, the add_options_page() call refers to the my_plugin_options() function which contains the actual page to be displayed (and PHP code to be processed) when someone clicks the menu item.
These processes are described in more detail in the sections below. Remember to enclose the creation of the menu and the page in functions, and use the admin_menu hook to get the whole process started at the right time!
Before creating a new menu, first decide if the menu should be a top-level menu, or a sub-level menu item. A top-level menu displays as new section in the administration menus and contains sub-level menu items. A sub-level menu means the menu item is a member of an existing menu.
It is rare that a plugin would require the creation of a top-level menu. If the plugin introduces an entirely new concept or feature to WordPress, and needs many screens to do it, then that plugin may warrant a new top-level menu. Adding a top-level menu should only be considered if you really need multiple, related screens to make WordPress do something it was not originally designed to accomplish. Examples of new top-level menus might include job management or conference management. Please note with the native post type registration, WordPress automatically creates top-level menus to manage those features.
If the creation of a top-level menu is not necessary, decide under what top-level menu to place your sub-level menu item. As a point of reference, most plugins add sub-level menu items underneath existing WordPress top-level menus. For example, the Backup plugin adds a sub-level menu option to the Tools top-level menu. Please note with the taxonomy registration, WordPress automatically creates sub-level menus under the applicable top-level menu to manage those features.
Use this guide of the WordPress top-level menus to determine the correct location for your sub-level menu item:
Now that you have decided where to add your top-level or sub-level menu, the next step is to tell WordPress about your new pages. All of this will take place in a function registered to the 'admin_menu' action. A working example is presented at the end of this section.
If you have decided your plugin requires a brand-new top-level menu, the first thing you'll need to do is to create one with the add_menu_page function. Note: skip to Sub-Level Menus if you don't need a top-level menu.
<?php add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position ); ?>
Parameter values:
Once your top-level menu is defined, or you have chosen to use an existing WordPress top-level menu, you are ready to define one or more sub-level menu items using the add_submenu_page function. Make sure to add the sub-level menu items in the order you want them displayed.
<?php add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Parameter values:
Here's a quick example illustrating how to insert a top-level menu page and a sub-menu page, where the title on the sub-menu page is different from the top-level page. In this example, 'my_magic_function' is the name of the function that displays the first sub-menu page:
<?php
add_menu_page('Page title', 'Top-level menu title', 'manage_options', 'my-top-level-handle', 'my_magic_function');
add_submenu_page( 'my-top-level-handle', 'Page title', 'Sub-menu title', 'manage_options', 'my-submenu-handle', 'my_magic_function');
?>
Here's an example of adding an option page under a custom post type menu block (see also here):
<?php add_submenu_page('edit.php?post_type=wiki', 'Options', 'Options', 'manage_options', 'wiki-options', array(&$this, 'options_page') ); ?>
Since most sub-level menus belong under the Settings, Tools, or Appearance menus, WordPress supplies wrapper functions that make adding a sub-level menu items to those top-level menus easier. Note that the function names may not match the names seen in the Administration Screens as they have changed over time:
Dashboard
<?php add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Posts
<?php add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Media
<?php add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Pages
<?php add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Comments
<?php add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Appearance
<?php add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Plugins
<?php add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Users
<?php add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Tools
<?php add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Settings
<?php add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function); ?>
Also see Creating Options Pages for more on this.
Here is an example of a WordPress plugin that inserts new menus into various places:
<?php /* Plugin Name: Menu Test Plugin URI: http://codex.wordpress.org/Adding_Administration_Menus Description: Menu Test Author: Codex authors Author URI: http://example.com */ // Hook for adding admin menus add_action('admin_menu', 'mt_add_pages'); // action function for above hook function mt_add_pages() { // Add a new submenu under Settings: add_options_page(__('Test Settings','menu-test'), __('Test Settings','menu-test'), 'manage_options', 'testsettings', 'mt_settings_page'); // Add a new submenu under Tools: add_management_page( __('Test Tools','menu-test'), __('Test Tools','menu-test'), 'manage_options', 'testtools', 'mt_tools_page'); // Add a new top-level menu (ill-advised): add_menu_page(__('Test Toplevel','menu-test'), __('Test Toplevel','menu-test'), 'manage_options', 'mt-top-level-handle', 'mt_toplevel_page' ); // Add a submenu to the custom top-level menu: add_submenu_page('mt-top-level-handle', __('Test Sublevel','menu-test'), __('Test Sublevel','menu-test'), 'manage_options', 'sub-page', 'mt_sublevel_page'); // Add a second submenu to the custom top-level menu: add_submenu_page('mt-top-level-handle', __('Test Sublevel 2','menu-test'), __('Test Sublevel 2','menu-test'), 'manage_options', 'sub-page2', 'mt_sublevel_page2'); } // mt_settings_page() displays the page content for the Test Settings submenu function mt_settings_page() { echo "<h2>" . __( 'Test Settings', 'menu-test' ) . "</h2>"; } // mt_tools_page() displays the page content for the Test Tools submenu function mt_tools_page() { echo "<h2>" . __( 'Test Tools', 'menu-test' ) . "</h2>"; } // mt_toplevel_page() displays the page content for the custom Test Toplevel menu function mt_toplevel_page() { echo "<h2>" . __( 'Test Toplevel', 'menu-test' ) . "</h2>"; } // mt_sublevel_page() displays the page content for the first submenu // of the custom Test Toplevel menu function mt_sublevel_page() { echo "<h2>" . __( 'Test Sublevel', 'menu-test' ) . "</h2>"; } // mt_sublevel_page2() displays the page content for the second submenu // of the custom Test Toplevel menu function mt_sublevel_page2() { echo "<h2>" . __( 'Test Sublevel2', 'menu-test' ) . "</h2>"; } ?>
Note: See the Settings API for information on creating settings pages.
The example above contains several dummy functions, such as mt_settings_page, as placeholders for actual page content. We need to turn them into real menu pages. So, let's assume that our plugin has an option called mt_favorite_color, and that we want to allow the site owner to type in his/her favorite color via a Settings page. The mt_options_page function will need to put a data entry form on the screen to enable this, and also process the entered data. Here is a function that does this:
// mt_settings_page() displays the page content for the Test Settings submenu function mt_settings_page() { //must check that the user has the required capability if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.') ); } // variables for the field and option names $opt_name = 'mt_favorite_color'; $hidden_field_name = 'mt_submit_hidden'; $data_field_name = 'mt_favorite_color'; // Read in existing option value from database $opt_val = get_option( $opt_name ); // See if the user has posted us some information // If they did, this hidden field will be set to 'Y' if( isset($_POST[ $hidden_field_name ]) && $_POST[ $hidden_field_name ] == 'Y' ) { // Read their posted value $opt_val = $_POST[ $data_field_name ]; // Save the posted value in the database update_option( $opt_name, $opt_val ); // Put a "settings saved" message on the screen ?> <div class="updated"><p><strong><?php _e('settings saved.', 'menu-test' ); ?></strong></p></div> <?php } // Now display the settings editing screen echo '<div class="wrap">'; // header echo "<h2>" . __( 'Menu Test Plugin Settings', 'menu-test' ) . "</h2>"; // settings form ?> <form name="form1" method="post" action=""> <input type="hidden" name="<?php echo $hidden_field_name; ?>" value="Y"> <p><?php _e("Favorite Color:", 'menu-test' ); ?> <input type="text" name="<?php echo $data_field_name; ?>" value="<?php echo $opt_val; ?>" size="20"> </p><hr /> <p class="submit"> <input type="submit" name="Submit" class="button-primary" value="<?php esc_attr_e('Save Changes') ?>" /> </p> </form> </div> <?php }
A few notes:
Every function that adds a new administration menu (add_menu_page(), add_submenu_page() and its specialized versions such as add_options_page()) returns a special value called Page Hook Suffix. It can be used later as a hook to which an action called only on that particular page can be registered.
One such action hook is load-{page_hook}, where {page_hook} is the value returned by one of these add_*_page() functions. This hook is called when the particular page is loaded. In the example below, it is used to display the "Plugin is not configured" notice on all admin pages except for plugin's options page:
<?php add_action('admin_menu', 'my_plugin_menu'); // Here you can check if plugin is configured (e.g. check if some option is set). If not, add new hook. // In this example hook is always added. add_action( 'admin_notices', 'my_plugin_admin_notices' ); function my_plugin_menu() { // Add the new admin menu and page and save the returned hook suffix $hook_suffix = add_options_page('My Plugin Options', 'My Plugin', 'manage_options', 'my-unique-identifier', 'my_plugin_options'); // Use the hook suffix to compose the hook and register an action executed when plugin's options page is loaded add_action( 'load-' . $hook_suffix , 'my_load_function' ); } function my_load_function() { // Current admin page is the options page for our plugin, so do not display the notice // (remove the action responsible for this) remove_action( 'admin_notices', 'my_plugin_admin_notices' ); } function my_plugin_admin_notices() { echo "<div id='notice' class='updated fade'><p>My Plugin is not configured yet. Please do it now.</p></div>\n"; } function my_plugin_options() { if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.') ); } echo '<div class="wrap">'; echo '<p>Here is where the form would go if I actually had options.</p>'; echo '</div>'; } ?>