主题作者可能需要提供一个设置屏幕,以便用户可以定制其主题的用法或工作方式。执行此操作的最佳方法是创建一个管理菜单项,允许用户从所有管理屏幕访问该设置屏幕。
函数参考
菜单页面
add_menu_page()add_object_page()add_utility_page()remove_menu_page()
子菜单页面
add_submenu_page()remove_submenu_page()
WordPress 管理菜单
add_dashboard_page()add_posts_page()add_media_page()add_links_page()add_pages_page()add_comments_page()add_theme_page()add_plugins_page()add_users_page()add_management_page()add_options_page()
每个情节都需要一个钩子
要添加管理菜单,您需要做三件事:
- 创建一个包含菜单构建代码的函数。
- 使用
admin_menu操作钩子注册上述函数 – 或者如果您正在为网络添加菜单,则使用network_admin_menu。 - 创建屏幕的 HTML 输出,当点击该菜单项时显示此内容。
大多数开发人员忽略了列表中的第二步。您不能简单地调用菜单代码。您需要将其放在一个函数内,然后注册此函数。
以下是这三个步骤描述的简单示例。这将添加设置顶级菜单下的子级菜单项。选择时,该菜单项将显示非常基本的屏幕。
<?php
/** 第 2 步(来自上面的文本)。 */
add_action( 'admin_menu', 'my_menu' );
/** 第 1 步。 */
function my_menu() {
add_options_page(
'My Options',
'My Menu',
'manage_options',
'my-unique-identifier',
'my_options'
);
}
/** 第 3 步。 */
function my_options() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( '您没有足够的权限访问此页面。' ) );
}
echo '这里是我输出屏幕 HTML 的地方';
echo '</div><pre>';
}在此示例中,函数 my_menu() 通过 add_options_page() 函数向设置管理菜单添加一个新项。
注意:请注意第 2 步中的 add_action() 调用在 admin_menu 钩子下注册了 my_menu() 函数。如果没有那个 add_action() 调用,将抛出未定义函数的 PHP 错误。最后,add_options_page() 调用引用包含当有人点击菜单项时要显示的页面(以及要处理的 PHP 代码)的 my_options() 函数。
这些步骤在下面各节中更详细地描述。请记住将菜单和页面的创建放在函数内,并使用 admin_menu 钩子 (hook) 在正确的时间启动整个过程。
确定新菜单的位置
在创建新菜单之前,首先决定该菜单应该是顶级菜单还是子级菜单项。顶级菜单作为管理菜单中的新部分显示,并包含子级菜单项。这意味着子级菜单项是现有顶级菜单的成员。
主题很少需要创建新的顶级菜单。如果主题向 WordPress 引入了全新的概念并且需要许多屏幕来实现它,那么该主题可能值得一个新的顶级菜单。只有在您确实需要多个相关屏幕来使 WordPress 完成其原本未设计要完成的某些任务时,才应考虑添加顶级菜单。新顶级菜单的示例可能包括工作管理或会议管理。请注意,使用原生的 文章类型 注册功能,WordPress 会自动创建用于管理此类功能的顶级菜单。
如果不需要创建顶级菜单,您需要决定将新的子级菜单项放在哪个顶级菜单下。作为参考点,几个主题在现有的 WordPress 顶级菜单下添加子级菜单项。
使用此指南确定您的子级菜单项的正确位置:
- 仪表板 (Dashboard) – 包含有关您站点中心的信息以及用于更新 WordPress 核心、插件和主题的“更新”选项。
- 文章 (Posts) – 显示撰写文章的(时间导向内容)工具。
- 媒体 (Media) – 上传和管理您的图片、视频和音频。
- 链接 (Links) – 管理对其他博客和相关站点的引用。
- 页面 (Pages) – 显示撰写称为页面的静态内容的工具。
- 评论 (Comments) – 控制和调节读者对文章回复的响应。
- 外观 (Appearance) – 显示用于操纵主题/样式文件、侧边栏等的控件。
- 插件 (Plugins) – 显示处理插件管理的控件,而不是插件本身的配置选项。
- 用户 (Users) – 显示用户管理控件。
- 工具 (Tools) – 管理博客数据的导出、导入甚至备份。
- 设置 (Settings) – 仅管理员应查看的插件选项。
- 网络管理 (Network Admin) – 显示在网络上设置的插件选项。而不是使用
admin_menu,您应该使用network_admin_menu(另见 创建网络)
顶级菜单
如果您决定您的主题需要全新的顶级菜单,您需要做的第一件事是使用 add_menu_page() 函数创建一个。注意:如果不需要顶级菜单,请跳转到子级菜单。
参数值:
page_title– 当选择该菜单时,在页面的标题标签中显示的文本。menu_title– 屏幕上的菜单名称文本。capability– 此菜单显示给用户所需的权限。在使用 Settings API 处理您的表单时,您应该在这里使用manage_options,否则用户将无法保存选项。用户级别已弃用且不应在此处使用。menu_slug– 引用该菜单的 slug 名称(对此菜单应该是唯一的)。在版本 3.0 之前,这被称为文件 (file) 或句柄 (handle) 参数。如果省略函数参数,menu_slug应为由 PHP 文件处理的显示菜单页面内容的文件。function– 用于显示菜单页面的页面内容的函数。icon_url– 为此菜单使用的图标的 URL。此参数是可选的。position– 该菜单在菜单顺序中的位置。默认情况下,如果省略此参数,菜单将出现在菜单结构的底部。要查看当前的菜单位置,请在加载菜单后使用print_r( $GLOBALS[ 'menu' ] )。- 子级菜单 (Sub-Level Menus) – 一旦您的顶级菜单已定义,或者您选择使用现有的 WordPress 顶级菜单,您就可以准备好使用
add_submenu_page()函数定义一个或多个子级菜单项。
子级菜单
如果您希望新菜单项为子菜单项,您可以改用 add_submenu_page() 函数创建它。
参数值:
parent_slug– 父菜单的 slug 名称,或提供您想插入其子菜单的标准 WordPress admin 文件的文件名,或者如果此子菜单要进入自定义顶级菜单则是您的插件文件。示例:- 仪表板 (Dashboard) –
add_submenu_page('index.php', ...) - 文章 (Posts) –
add_submenu_page('edit.php', ...) - 媒体 (Media) –
add_submenu_page('upload.php', ...) - 链接 (Links) –
add_submenu_page('link-manager.php', ...) - 页面 (Pages) –
add_submenu_page('edit.php?post_type=page', ...) - 评论 (Comments) –
add_submenu_page('edit-comments.php', ...) - 自定义文章类型 (Custom Post Types) –
add_submenu_page('edit.php?post_type=your_post_type', ...) - 外观 (Appearance) –
add_submenu_page('themes.php', ...) - 插件 (Plugins) –
add_submenu_page('plugins.php', ...) - 用户 (Users) –
add_submenu_page('users.php', ...) - 工具 (Tools) –
add_submenu_page('tools.php', ...) - 设置 (Settings) –
add_submenu_page('options-general.php', ...)
- 仪表板 (Dashboard) –
page_title– 当子菜单激活时,将放入页面 HTML 标题的文本。menu_title– 当选择该菜单时在页面的标题标签中显示的文本。capability– 此菜单显示给用户所需的权限。用户级别已弃用且不应在此处使用。menu_slug– 对于现有的 WordPress 菜单,处理显示菜单页面内容的 PHP 文件。对于自定义顶级菜单的子菜单,这是该子菜单页面的唯一标识符。function– 用于显示菜单页面的页面内容的函数。从技术上讲,就像在add_menu_page函数中一样,函数参数是可选的,但如果未提供它,那么 WordPress 基本上将假设包含 PHP 文件将生成管理屏幕,而不调用函数。
使用包装器函数
由于大多数子级菜单属于设置、工具或外观菜单之下,WordPress 提供包装器函数以简化向这些顶级菜单添加子级菜单项。请注意,函数名称可能与在管理 UI 中看到的名称不匹配,因为它们随时间发生了变化:
仪表板
<?php
add_dashboard_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);文章
<?php
add_posts_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);媒体
<?php
add_media_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);链接
<?php
add_links_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);页面
<?php
add_pages_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);评论
add_comments_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);外观
<?php
add_theme_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);插件
<?php
add_plugins_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);用户
<?php
add_users_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);工具
<?php
add_management_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);设置
<?php
add_options_page(
$page_title,
$menu_title,
$capability,
$menu_slug,
$function
);另请参阅 主题选项 (Theme Options) 以了解当前通过自定义器 API 创建选项的推荐方法。
示例
这是一个快速示例,说明了如何插入顶级菜单页面和子菜单页面,其中子菜单页面的标题与顶级页面不同。在此示例中,register_my_theme_more_settings_menu 是显示第一个子菜单页面的函数名称:
<?php
function register_my_theme_settings_menu() {
add_menu_page(
"My Theme's Settings",
'My Theme',
'manage_options',
'my-theme-settings-menu'
);
}
function register_my_theme_more_settings_menu() {
add_submenu_page(
'my-theme-settings-menu',
'More Settings for My Theme',
'More Settings',
'manage_options',
'my-theme-more-settings-menu'
);
}
add_action( 'admin_menu', 'register_my_theme_settings_menu' );
add_action( 'admin_menu', 'register_my_theme_more_settings_menu' );这是一个在自定义文章类型菜单块下添加选项页面的示例(另见此处):
代码 (CODE)
插入页面
这是如何将多个菜单插入到各种位置的示例:
<?php
// 用于添加管理菜单的钩子
add_action( 'admin_menu', 'mt_add_pages' );
// 上述钩子的操作函数
function mt_add_pages() {
// 在设置下添加新的子菜单:
add_options_page( __( '测试设置', 'menu-test' ), __( '测试设置', 'menu-test' ), 'manage_options', 'testsettings', 'mt_settings_page' );
// 在工具下添加新的子菜单:
add_management_page( __( '测试工具', 'menu-test' ), __( '测试工具', 'menu-test' ), 'manage_options', 'testtools', 'mt_tools_page' );
// 添加一个新的顶级菜单(不推荐):
add_menu_page( __( '测试顶级', 'menu-test' ), __( '测试顶级', 'menu-test' ), 'manage_options', 'mt-top-level-handle', 'mt_toplevel_page' );
// 向自定义顶级菜单添加子菜单:
add_submenu_page( 'mt-top-level-handle', __( '测试子级', 'menu-test' ), __( '测试子级', 'menu-test' ), 'manage_options', 'sub-page', 'mt_sublevel_page' );
// 向自定义顶级菜单添加第二个子菜单:
add_submenu_page( 'mt-top-level-handle', __( '测试子级 2', 'menu-test' ), __( '测试子级 2', 'menu-test' ), 'manage_options', 'sub-page2', 'mt_sublevel_page2' );
}
// mt_settings_page() 显示“测试设置”子菜单的页面内容。
function mt_settings_page() {
echo '</pre><h2>' . __( '测试设置', 'menu-test' ) . '</h2><pre>';
}
// mt_tools_page() 显示“测试工具”子菜单的页面内容。
function mt_tools_page() {
echo '</pre><h2>' . __( '测试工具', 'menu-test' ) . '</h2><pre>';
}
// mt_toplevel_page() 显示自定义“测试顶级”菜单的页面内容。
function mt_toplevel_page() {
echo '</pre><h2>' . __( '测试顶级', 'menu-test' ) . '</h2><pre>';
}
// mt_sublevel_page() 显示自定义“测试顶级”菜单的第一个子菜单的页面内容。
function mt_sublevel_page() {
echo '</pre><h2>' . __( '测试子级', 'menu-test' ) . '</h2><pre>';
}
// mt_sublevel_page2() 显示自定义“测试顶级”菜单的第二个子菜单的页面内容。
function mt_sublevel_page2() {
echo '</pre><h2>' . __( '测试子级 2', 'menu-test' ) . '</h2><pre>';
}示例菜单页面
注意:请参阅 设置 API (Settings API) 以获取有关创建设置页面的信息。
前面的示例包含几个虚拟函数,如 mt_settings_page(),作为实际页面内容的占位符。让我们扩展它们。如果您想创建一个名为 mt_favorite_color 的选项,允许网站所有者通过设置页面输入他们最喜欢的颜色怎么办?mt_options_page() 函数将需要在屏幕上输出数据条目表单,并处理输入的数据。
这是一个执行此操作的函数:
<?php
// mt_settings_page() 显示“测试设置”子菜单的页面内容。
function mt_settings_page() {
// 必须检查用户是否具有所需的权限。
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( '您没有足够的权限访问此页面。' ) );
}
// 字段和选项名称的变量
$opt_name = 'mt_favorite_color';
$hidden_field_name = 'mt_submit_hidden';
$data_field_name = 'mt_favorite_color';
// 从数据库读取现有选项值
$opt_val = get_option( $opt_name );
// 查看用户是否向我们提交了一些信息。如果他们提交了,此隐藏字段将设置为'Y'。
if ( isset( $_POST[ $hidden_field_name ] ) && $_POST[ $hidden_field_name ] == 'Y' ) {
// 读取他们提交的值。
$opt_val = $_POST[ $data_field_name ];
// 将提交的值保存到数据库。
update_option( $opt_name, $opt_val );
// 在屏幕上放置“设置已更新”消息
?>
<div class="updated"></div><!-- .updated -->
<div class="wrap">
<?php echo '<h2>' . __( '菜单测试设置', 'menu-test' ) . '</h2>'; ?>
<form action="" method="post" name="form1"></form>
<?php _e( '最喜欢的颜色:', 'menu-test' ); ?>
<hr />
</div><!-- .wrap -->
<?php
}
}几点说明:
- WordPress 函数如
add_menu_page()和add_submenu_page()接受一个权限,将用于确定是否显示顶级或子级菜单。 - 钩入处理页面输出的函数也必须检查用户是否具有所需的权限。
- WordPress 管理函数负责验证用户登录,因此您不必在您的函数中担心它。
- 上面的函数示例已国际化 — 请参阅 为 WordPress 开发人员提供的 I18n 以获取更多信息。
- 该函数在处理任何输入数据并将其放在屏幕上之前,将新值显示在表单中(而不是数据库中的值)。
- 您不必担心第一次运行是否有效,因为如果
update_option函数不存在于数据库中,WordPress 的update_option函数会自动添加一个选项到数据库。 - 这些管理菜单添加过程在每次导航到 Admin(后台)中的页面时都会解析。所以如果您正在编写一个没有选项页面的主题但稍后添加了一个,您可以仅使用上述说明添加它并重新上传,然后调整直到您满意为止。换句话说,菜单不是“永久添加”或激活主题时放入数据库的。它们是即时解析的,因此您可以随意添加或删除菜单项,重新上传,更改将立即反映。
页面钩子后缀
每个添加新管理菜单的函数 – add_menu_page(), add_submenu_page() 及其专用版本如 add_options_page() – 返回一个称为页面钩子后缀 (Page Hook Suffix)的特殊值。它可以稍后用作仅在特定页面上调用的操作注册的钩子。
其中一个这样的动作钩子是 load-{page_hook},其中 {page_hook} 是这些 add_*_page() 函数之一返回的值。当加载该特定页面时调用此钩子。在下面的示例中,它用于在所有管理页面上(插件的选项页面除外)显示“主题未配置”通知:
<?php
add_action( 'admin_menu', 'my_menu' );
// 在这里您可以检查插件是否已配置(例如,检查某些选项是否设置)。如果没有,则添加新钩子。
// 在此示例中总是添加钩子。
add_action( 'admin_notices', 'my_admin_notices' );
function my_menu() {
// 添加新的管理菜单和页面并保存返回的钩子后缀
$hook_suffix = add_options_page( 'My Options', 'My Theme', 'manage_options', 'my-unique-identifier', 'my_options' );
// 使用钩子后缀组合钩子并注册在插件选项页面加载时执行的操作
add_action( 'load-' . $hook_suffix, 'my_load_function' );
}
function my_load_function() {
// 当前管理页面是我们要使用的插件的选项页面,因此不要显示通知
// (移除负责此操作的动作)
remove_action( 'admin_notices', 'my_admin_notices' );
}
function my_admin_notices() {
echo '<pre><div class="updated fade" id="notice">我的插件尚未配置。请现在进行配置</div></pre>';
}
function my_options() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( '您没有足够的权限访问此页面。' ) );
}
echo '</pre><div class="wrap">';
echo '这里是我实际有选项时表单将去的地方';
echo '</div><pre>';
}