Languages: English • 中文(简体) • Administration Menus 日本語 Русский • (Add your language)
通常情况下,插件和主题的作者都需要为其提供一个配置界面,以方便用户去自定义它们。将这个配置界面展示给用户的最好方式,就是在后台管理员界面的配置菜单中添加一个选项,然后当用户点击这个选项的时候再去打开它。这篇文章将会告诉你如何去实现这样的事情。
注意:在继续阅读之前,你应当对如何写一个插件,以及Actions和Filters的插件API函数有一定的了解。
|
|
想要向管理员界面的配置菜单中添加一个选项,你必须要完成三件事:
第二步是新手们往往会忽略掉的步骤。必须要记住:光写出代码是不够的,你还必须要把这段代码放到一个函数中,并且把这个函数挂载到相应的钩子上,它才能发挥相应的作用。
以下是包含这三个步骤的简单示例。这个插件将会在设置菜单的主选项下创建一个子选项,当该选项被点击时,将会显示出一个非常简单的页面。
注意:这些代码应当被写到PHP主文件中,或是一个单独的PHP文件中。
<?php /** 第1步:定义添加菜单选项的函数 */ function my_plugin_menu() { add_options_page( 'My Plugin Options', 'My Plugin', 'manage_options', 'my-unique-identifier', 'my_plugin_options' ); } /** 第2步:将函数注册到钩子中 */ add_action( 'admin_menu', 'my_plugin_menu' ); /** 第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>'; } ?>
在第1步中,my_plugin_menu()函数的作用是通过调用add_options_page()函数,向管理员界面的配置菜单中添加一个新的菜单选项(关于更复杂的多级选项,将在之后进行详述)。
在第2步中,add_action()函数的作用就是将第1步中定义的my_plugin_menu()函数,挂载到名为admin_menu的钩子下。此时如果忘了调用add_action()函数的话,那么在你试图激活这个插件时就会提示'undefined function'错误。
在最后一步中,my_plugin_options()函数的作用就是显示一个配置页面,并显示出用户可配置的内容(可以由PHP的代码编写),这个函数也是在第1步中的add_action()函数中被调用的。这样当用户点击菜单选项的时候,就会弹出这个配置页面。
在下面的章节中,将会对这些步骤进行更详细的说明。再重复一遍:切记要把创建菜单选项的代码放到函数中!并且记得将函数挂载到admin_menu钩子中!这样你的整个代码流程才能正确的运行。
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-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 页面 and a sub-menu page, where the title on the sub-menu 页面 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 页面 under a custom 日志 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 admin UI 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); ?>
Links
<?php add_links_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 页面 content for the Test settings submenu function mt_settings_page() { echo "<h2>" . __( 'Test Settings', 'menu-test' ) . "</h2>"; } // mt_tools_page() displays the 页面 content for the Test Tools submenu function mt_tools_page() { echo "<h2>" . __( 'Test Tools', 'menu-test' ) . "</h2>"; } // mt_toplevel_page() displays the 页面 content for the custom Test Toplevel menu function mt_toplevel_page() { echo "<h2>" . __( 'Test Toplevel', 'menu-test' ) . "</h2>"; } // mt_sublevel_page() displays the 页面 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 页面 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 页面 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 页面 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 an settings updated 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 页面 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 页面 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 页面 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 页面 is loaded add_action( 'load-' . $hook_suffix , 'my_load_function' ); } function my_load_function() { // Current admin 页面 is the options 页面 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>'; } ?>