管理菜单

这不再是使用主题选项的推荐方式。建议使用Customizer API,以便为用户提供更多控制和灵活性。

主题作者可能需要提供一个设置界面,以便用户可以自定义其主题的使用或工作方式。最好的方法是创建一个管理菜单项,该菜单项允许用户从所有管理界面访问该设置界面。

函数参考

菜单页面

子菜单页面

WordPress管理菜单

每个情节都需要一个钩子

要添加管理菜单,您需要做三件事:

  1. 创建一个包含菜单构建代码的函数。
  2. 如果要为网络添加菜单,请使用admin_menu动作挂钩-或network_admin_menu 注册上述函数 。
  3. 创建界面的HTML输出,单击菜单项时显示该界面。

大多数开发人员忽略了此列表中的第二步。您不能简单地调用菜单代码。您需要将其放在一个函数中,然后注册该函数。

这是描述的这三个步骤的简单示例。这将在“设置”顶级菜单下添加一个子菜单项。选择后,该菜单项将显示一个非常基本的界面。

<?php
/** Step 2 (from text above). */
add_action( 'admin_menu', 'my_menu' );
 
/** Step 1. */
function my_menu() {
    add_options_page(
        'My Options',
        'My Menu',
        'manage_options',
        'my-unique-identifier',
        'my_options'
    );
}
 
/** Step 3. */
function my_options() {
    if ( !current_user_can( 'manage_options' ) ) {
        wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
    }
    echo 'Here is where I output the HTML for my screen.';
    echo '</div><pre>';
}
?>

在此示例中,函数my_menu()通过函数 add_options_page() 将新项目添加到“设置”管理菜单。

注意:请注意,步骤2 中的add_action()调用将my_menu()函数注册admin_menu挂钩下。否则,add_action()调用将引发未定义函数的PHP错误。最后,add_options_page()调用的my_options()包含某人单击菜单项时要显示的实际页面(以及要处理的PHP代码)的函数。

在下面的章节中将更详细地描述这些步骤。请记住将菜单和页面的创建包含在函数中,并使用该admin_menu 挂钩在正确的时间启动整个过程。

确定新菜单位置

在创建新菜单之前,首先确定该菜单是顶级菜单还是子菜单项。顶级菜单在管理菜单中显示为新部分,并包含子级菜单项。这意味着子级菜单项是现有顶级菜单的成员。

很少有主题需要创建一个新的顶层菜单。如果主题为WordPress引入了一个全新的概念并且需要很多界面来实现,则该主题可能需要一个新的等级菜单。仅当您确实需要多个相关界面以使WordPress执行其最初设计无法完成的操作时,才应考虑添加顶级菜单。新的顶级菜单的示例可能包括作业管理或会议( conference )管理。请注意,通过内置的文章类型注册,WordPress会自动创建顶级菜单来管理此类功能。

如果不需要创建顶级菜单,则需要决定在哪个顶级菜单下放置新的子级菜单项。

可以根据WordPress顶级菜单的位置来确定子菜单项的正确位置:

  • 仪表板–您站点的信息中心,包括用于更新WordPress核心、插件和主题的“更新”选项。
  • 文章–显示用于撰写文章的工具。
  • 媒体–上传和管理您的图片、视频和音频。
  • 链接–管理对其他博客和感兴趣站点的引用。(已弃用)
  • 页面–显示用于编写称为页面的静态内容的工具。
  • 评论–控制和规范读者对文章的回应。
  • 外观–显示用于控制主题/样式文件、侧边栏等控件。
  • 插件–显示有关插件管理的控件,而不是插件本身的配置选项。
  • 用户–显示用于用户管理的控件。
  • 工具–管理博客数据的导出,导入,甚至备份。
  • 设置–显示只有管理员才能查看的插件选项。
  • 网络管理员–显示在多站点网络上设置选项。对于注册网络菜单,不要用admin_menu,应该使用network_admin_menu(另请参阅创建网络

顶级菜单

如果您确定主题需要全新的顶级菜单,则要做的第一件事就是使用该函数add_menu_page()创建一个菜单。注意:如果不需要顶级菜单,跳至“ 子菜单”。

参数值:

  • page_title –选择菜单后在页面标题标签中显示的文本。
  • menu_title –菜单的界面名称文本。
  • capability–向用户显示此菜单所需的用户权限。使用设置API处理表单时,应在此处使用 manage_options,因为如果没有表单,用户将无法保存选项。用户级别已弃用,在此不应该使用。
  • menu_slug–引用此菜单所依据的子名称(此菜单应唯一)。在3.0版之前,这称为文件(或句柄)参数。如果省略function参数,menu_slug则应为处理菜单页面内容显示的PHP文件。
  • function –显示菜单页面内容的函数。
  • icon_url–此菜单使用的图标的位置。此参数是可选的。
  • position–该菜单应在菜单顺序中出现的位置。默认情况下,如果省略此参数,则菜单将出现在菜单结构的底部。要查看当前菜单位置, 请在菜单加载后使用print_r( $GLOBALS[ 'menu' ] )
  • 子菜单–定义了顶层菜单或选择使用现有的WordPress顶级菜单后,即可使用该add_submenu_page()函数定义一个或多个子级菜单项。

子菜单

如果您希望新菜单项作为子菜单项,则可以使用add_submenu_page()函数来创建它。

参数值:

  • parent_slug–父级菜单的slug别名,或提供要在其中插入子菜单的顶级菜单的标准WordPress管理文件的文件名,如果此子菜单进入自定义顶级菜单。例子:
    • 仪表板 - add_submenu_page('index.php', ...)
    • 文章– add_submenu_page('edit.php', ...)
    • 媒体– add_submenu_page('upload.php', ...)
    • 链接– add_submenu_page('link-manager.php', ...)
    • 页面– add_submenu_page('edit.php?post_type=page', ...)
    • 评论 - add_submenu_page('edit-comments.php', ...)
    • 自定义文章类型– add_submenu_page('edit.php?post_type=your_post_type', ...)
    • 外观– add_submenu_page('themes.php', ...)
    • 插件– add_submenu_page('plugins.php', ...)
    • 用户– add_submenu_page('users.php', ...)
    • 工具– add_submenu_page('tools.php', ...)
    • 设置– add_submenu_page('options-general.php', ...)
  • page_title –子菜单页面标题的文本。
  • menu_title –选择菜单后在页面标题标签中显示的文本。
  • capability–向用户显示此菜单所需的用户权限。用户级别已弃用,在此不应该使用。
  • menu_slug–对于现有的WordPress菜单,该PHP文件用于处理菜单页面内容的显示。对于自定义顶级菜单的子菜单,是此子菜单页面的唯一标识符。
  • function–显示菜单页面内容的函数。从技术上讲,就像在add_menu_page函数中一样,function参数是可选的,但是如果未提供该参数,则WordPress将默认认为该PHP文件将生成管理界面,而无需调用函数。

使用包装函数

由于大多数子菜单都位于“设置”、“工具”或“外观”菜单下,因此WordPress提供了包装函数,这些函数使将子菜单项添加到这些顶级菜单变得更加容易。请注意,函数名称可能与在管理界面中看到的名称不匹配,因为它们随着时间的推移而发生了变化:

仪表板

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

评论

<?php 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); ?>

另请参阅主题选项,以了解当前推荐的通过Customizer API创建选项的方式。

示例

这是一个快速示例,说明了如何插入顶级菜单页面和子菜单页面,其中子菜单页面上的标题与顶级页面不同。在此示例中,register_my_theme_more_settings_menu是显示第一个子菜单页面的函数的名称:

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-themes-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");

插入页面

这是一个如何在多个位置插入多个菜单的示例:

<?php
// 添加管理菜单的钩子
add_action('admin_menu', 'mt_add_pages');
 
// 挂载到上面钩子的函数
function mt_add_pages() {
// 在设置下添加子菜单
add_options_page(__('Test Settings','menu-test'), __('Test Settings','menu-test'), 'manage_options', 'testsettings', 'mt_settings_page');
 
// 在工具下添加子菜单
add_management_page( __('Test Tools','menu-test'), __('Test Tools','menu-test'), 'manage_options', 'testtools', 'mt_tools_page');
 
// 添加顶级菜单
add_menu_page(__('Test Toplevel','menu-test'), __('Test Top-level','menu-test'), 'manage_options', 'mt-top-level-handle', 'mt_toplevel_page' );
 
//添加子菜单到自定义的顶级菜单
add_submenu_page('mt-top-level-handle', __('Test Sub-Level','menu-test'), __('Test Sub-Level','menu-test'), 'manage_options', 'sub-page', 'mt_sublevel_page');
 
// 添加第二个子菜单到自定义的顶级菜单
add_submenu_page('mt-top-level-handle', __('Test Sub-Level 2','menu-test'), __('Test Sub-Level 2','menu-test'), 'manage_options', 'sub-page2', 'mt_sublevel_page2');
}
 
// mt_settings_page() 显示设置下子菜单页面的内容
function mt_settings_page() {
    echo "</pre>
    <h2>" . __( 'Test Settings', 'menu-test' ) . "</h2>
    <pre>
    ";
}
 
// mt_tools_page() 显示工具下子菜单的内容
function mt_tools_page() {
    echo "</pre>
    <h2>" . __( 'Test Tools', 'menu-test' ) . "</h2>
    <pre>
    ";
}
 
// mt_toplevel_page() 显示自定义顶级菜单的内容
function mt_toplevel_page() {
    echo "</pre>
    <h2>" . __( 'Test Top-Level', 'menu-test' ) . "</h2>
    <pre>
    ";
}
 
// mt_sublevel_page() 显示第一个子菜单的内容
// of the custom Test Toplevel menu
function mt_sublevel_page() {
    echo "</pre>
    <h2>" . __( 'Test Sub-Level', 'menu-test' ) . "</h2>
    <pre>
";
}
 
// mt_sublevel_page2() 显示第二个子菜单的内容
// of the custom Test Top-Level menu
function mt_sublevel_page2() {
    echo "</pre>
    <h2>" . __( 'Test Sub-Level 2', 'menu-test' ) . "</h2>
    <pre>
";
}
?>

菜单页示例

注意:有关创建设置页面的信息,请参见Settings API

前面的示例包含几个虚拟函数,例如mt_settings_page(),作为实际页面内容的占位符。让我们扩展它们。如果您想创建一个名为mt_favorite_color 的选项,该选项使站点所有者可以通过“设置”页面键入自己喜欢的颜色怎么办?mt_options_page()函数将需要在界面上输出数据输入表单,并处理输入的数据。

这是执行此操作的函数:

// 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>
 
<div class="wrap">
<?php
// Header
echo "<h2>" . __( 'Menu Test Settings', 'menu-test' ) . "</h2>";
 
// 设置表单
?>
<form action="" method="post" name="form1"></form>
<?php _e("Favorite Color:", 'menu-test' ); ?>
 
<hr />
</div>
<?php } ?>

一些注意事项:

  • WordPress函数(例如add_menu_page()和)add_submenu_page()具有将用于确定显示顶级菜单还是子菜单的功能。
  • 连接到处理页面输出的函数必须检查用户是否也具有所需的权限。
  • WordPress管理函数负责验证用户登录名,因此您不必在函数中担心它。
  • 上面的功能示例已国际化- 有关更多详细信息,请参见WordPress开发人员的I18n
  • 该函数在将数据输入表单显示在屏幕上之前会处理所有输入的数据,以便新的值可以在该表单显示(而不是数据库中的值)。
  • 您不必担心第一次工作,因为WordPress update_option函数会自动将选项添加到数据库(如果尚不存在)。
  • 每次您导航到Admin中的页面时,都会解析这些管理菜单的添加过程。因此,如果您编写的主题没有选项页面,但是以后添加了,则可以按照上述说明添加主题选项,然后重新上传,然后进行调整,直到满意为止。换句话说,激活主题后,菜单不会“永久添加”或放入数据库中。它们是动态解析的,因此您可以随意添加或减去菜单项,重新上传,更改将立即反映出来。

页面钩子后缀

增加管理菜单每一个函数:add_menu_page()add_submenu_page()都有其专有的版本,如add_options_page()-返回称为页面钩子后缀的特殊值。以后可以将它用作一个钩子,可以将仅在该特定页面上调用的操作注册到该钩子。

这样的动作挂钩之一是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">
    My Plugin is not configured yet. Please do it now.</div>
    </pre>';
}
 
function my_options() {
    if (!current_user_can('manage_options')) {
    wp_die( __('You do not have sufficient permissions to access this page.') );
    }
 
    echo '</pre>
    <div class="wrap">';
    echo 'Here is where the form would go if I actually had options.';
    echo '</div>
    <pre>
    ';
}
?>
该文章对您有帮助吗?

暂无评论

发表评论