深入理解 WordPress `admin_menu` 钩子源码:它在后台管理页面的加载流程中处于哪个阶段,以及如何通过它添加自定义菜单。

咳咳,各位同学,早上好(或者下午好,晚上好,取决于你们什么时候看这篇文章)。我是你们今天的 WordPress 后台菜单特讲讲师,人称“钩子小王子”(别问我为什么,可能因为我头发比较少)。

今天咱们来聊聊 WordPress 后台菜单的灵魂人物——admin_menu 钩子。这玩意儿,你如果玩转了,就能在 WordPress 后台呼风唤雨,想加啥菜单加啥菜单,想让菜单在哪儿显示就在哪儿显示,简直比上帝还上帝(开玩笑,别当真)。

咱们今天的内容主要分为以下几个部分:

  1. admin_menu 在 WordPress 后台加载流程中的位置: 咱们先搞清楚它在整个流程里扮演什么角色,就像知道一个演员在剧组里是主角还是跑龙套一样重要。
  2. admin_menu 钩子的基本用法: 就像学开车先学起步一样,先掌握基本用法,才能开飙车。
  3. add_menu_page() 函数详解: 这是添加顶级菜单的核武器,必须掌握。
  4. add_submenu_page() 函数详解: 这是添加子菜单的利器,有了它,你的菜单就能像树一样枝繁叶茂。
  5. 权限管理: 别以为加了菜单就万事大吉,还得考虑谁能看到,谁不能看到,就像保安一样,把好关。
  6. 高级技巧: 隐藏菜单、自定义菜单图标、动态菜单等,带你解锁更多姿势。
  7. 实战演练: 咱们来个实际的例子,把前面学的都用上,看看效果。
  8. 常见问题及解决方案: 踩过的坑,咱们总结一下,避免大家再掉进去。

1. admin_menu 在 WordPress 后台加载流程中的位置

想象一下,WordPress 后台的加载流程就像一个复杂的流水线,各种组件、函数、钩子按照一定的顺序依次执行。admin_menu 钩子,就位于这条流水线的中游,负责组装后台菜单。

具体来说,WordPress 在加载后台管理页面时,会按照以下步骤执行(简化版):

步骤 描述
1 加载 WordPress 核心文件和插件。
2 执行 plugins_loaded 钩子,插件完成初始化。
3 执行 after_setup_theme 钩子,主题完成初始化。
4 执行 admin_menu 钩子,添加后台菜单。
5 加载后台页面模板并显示。

可以看到,admin_menu 钩子是在插件和主题初始化之后,但在加载后台页面模板之前执行的。这意味着,你可以在这个钩子中,安全地访问插件和主题的功能,并根据它们的状态来动态地添加或修改菜单。

2. admin_menu 钩子的基本用法

admin_menu 钩子的用法很简单,就像给 WordPress 说:“嘿,老兄,我想往你后台加点东西,你帮我安排一下。”

你需要做的就是:

  1. 创建一个函数,这个函数负责添加菜单。
  2. 使用 add_action() 函数,将你的函数挂载到 admin_menu 钩子上。
<?php
// 创建一个函数,负责添加菜单
function my_custom_menu() {
  // 这里放添加菜单的代码
}

// 将函数挂载到 admin_menu 钩子上
add_action( 'admin_menu', 'my_custom_menu' );
?>

这段代码就像一个简单的约定,告诉 WordPress:“当 admin_menu 钩子被触发时,执行 my_custom_menu 函数。”

3. add_menu_page() 函数详解

add_menu_page() 函数是添加顶级菜单的核心函数,就像盖房子的地基一样重要。它的语法如下:

<?php
add_menu_page(
  string   $page_title,
  string   $menu_title,
  string   $capability,
  string   $menu_slug,
  callable $function = '',
  string   $icon_url = '',
  int      $position = null
);
?>

各个参数的含义如下:

参数 类型 描述
$page_title string 页面标题,显示在浏览器标签栏和 H1 标签中。
$menu_title string 菜单标题,显示在后台菜单中。
$capability string 访问权限,只有具有该权限的用户才能看到该菜单。例如 'manage_options' 表示只有管理员才能看到。
$menu_slug string 菜单别名,用于生成 URL。必须是唯一的,不能与其他菜单冲突。
$function callable 点击菜单后执行的函数。如果你想显示一个自定义页面,就在这个函数里编写页面内容。
$icon_url string 菜单图标的 URL。可以是 WordPress 自带的 Dashicons,也可以是自定义的图片 URL。如果留空,则使用默认图标。
$position int 菜单在后台菜单中的位置。数字越小,位置越靠前。如果留空,则自动添加到菜单的末尾。注意:这个位置不是绝对的,如果其他插件也设置了位置,可能会发生冲突。WordPress 预留了一些常用的位置,例如 5、10、15 等,建议使用这些预留位置。

举个例子,咱们来添加一个名为 "我的自定义菜单" 的顶级菜单,只有管理员才能访问,点击后显示一个简单的页面:

<?php
function my_custom_menu() {
  add_menu_page(
    '我的自定义页面', // 页面标题
    '我的自定义菜单', // 菜单标题
    'manage_options', // 访问权限
    'my-custom-menu', // 菜单别名
    'my_custom_page_content', // 点击菜单后执行的函数
    'dashicons-admin-tools', // 菜单图标
    25 // 菜单位置
  );
}

add_action( 'admin_menu', 'my_custom_menu' );

// 点击菜单后执行的函数
function my_custom_page_content() {
  echo '<h1>欢迎来到我的自定义页面!</h1>';
  echo '<p>这里可以放你的自定义内容。</p>';
}
?>

这段代码会在后台菜单中添加一个名为 "我的自定义菜单" 的顶级菜单,图标是工具箱,位置在 25。点击这个菜单,会显示一个标题为 "欢迎来到我的自定义页面!" 的页面。

4. add_submenu_page() 函数详解

add_submenu_page() 函数用于添加子菜单,就像在顶级菜单下添加分支一样。它的语法如下:

<?php
add_submenu_page(
  string   $parent_slug,
  string   $page_title,
  string   $menu_title,
  string   $capability,
  string   $menu_slug,
  callable $function = ''
);
?>

各个参数的含义如下:

参数 类型 描述
$parent_slug string 父级菜单的别名,也就是顶级菜单的 $menu_slug
$page_title string 页面标题,显示在浏览器标签栏和 H1 标签中。
$menu_title string 菜单标题,显示在后台菜单中。
$capability string 访问权限,只有具有该权限的用户才能看到该菜单。
$menu_slug string 菜单别名,用于生成 URL。必须是唯一的,不能与其他菜单冲突。
$function callable 点击菜单后执行的函数。如果你想显示一个自定义页面,就在这个函数里编写页面内容。

举个例子,咱们在 "我的自定义菜单" 下添加一个名为 "子菜单 1" 的子菜单:

<?php
function my_custom_menu() {
  add_menu_page(
    '我的自定义页面',
    '我的自定义菜单',
    'manage_options',
    'my-custom-menu',
    'my_custom_page_content',
    'dashicons-admin-tools',
    25
  );

  add_submenu_page(
    'my-custom-menu', // 父级菜单别名
    '子菜单 1 页面', // 页面标题
    '子菜单 1', // 菜单标题
    'manage_options', // 访问权限
    'my-custom-submenu-1', // 菜单别名
    'my_custom_submenu_1_content' // 点击菜单后执行的函数
  );
}

add_action( 'admin_menu', 'my_custom_menu' );

function my_custom_page_content() {
  echo '<h1>欢迎来到我的自定义页面!</h1>';
  echo '<p>这里可以放你的自定义内容。</p>';
}

function my_custom_submenu_1_content() {
  echo '<h1>欢迎来到子菜单 1 页面!</h1>';
  echo '<p>这里是子菜单 1 的内容。</p>';
}
?>

这段代码会在 "我的自定义菜单" 下添加一个名为 "子菜单 1" 的子菜单,点击这个子菜单,会显示一个标题为 "欢迎来到子菜单 1 页面!" 的页面。

5. 权限管理

权限管理是后台菜单安全的重要组成部分。add_menu_page()add_submenu_page() 函数的 $capability 参数就是用来控制访问权限的。

WordPress 提供了一系列预定义的权限,例如:

权限 描述
manage_options 管理员权限,可以访问所有后台设置。
edit_posts 编辑文章权限,可以创建、编辑和发布文章。
edit_pages 编辑页面权限,可以创建、编辑和发布页面。
upload_files 上传文件权限,可以上传图片、视频等文件。
moderate_comments 审核评论权限,可以审核、批准或删除评论。

你可以根据需要选择合适的权限。如果你想自定义权限,可以使用 add_cap() 函数。

6. 高级技巧

  • 隐藏菜单: 有时候,你可能想隐藏某个菜单,但又不想删除它。可以使用 remove_menu_page() 函数。

    <?php
    function my_custom_menu() {
      remove_menu_page( 'tools.php' ); // 隐藏 "工具" 菜单
    }
    
    add_action( 'admin_menu', 'my_custom_menu' );
    ?>
  • 自定义菜单图标: 除了使用 Dashicons,你还可以使用自定义的图片作为菜单图标。只需要将 $icon_url 参数设置为图片 URL 即可。

    <?php
    function my_custom_menu() {
      add_menu_page(
        '我的自定义页面',
        '我的自定义菜单',
        'manage_options',
        'my-custom-menu',
        'my_custom_page_content',
        plugin_dir_url( __FILE__ ) . 'images/my-icon.png', // 自定义图标 URL
        25
      );
    }
    
    add_action( 'admin_menu', 'my_custom_menu' );
    ?>
  • 动态菜单: 你可以根据不同的条件,动态地添加或修改菜单。例如,根据用户的角色、插件的状态等。

    <?php
    function my_custom_menu() {
      $current_user = wp_get_current_user();
      if ( in_array( 'editor', (array) $current_user->roles ) ) {
        // 如果当前用户是编辑,则添加一个特殊的菜单
        add_menu_page(
          '编辑专用页面',
          '编辑专用菜单',
          'edit_posts',
          'editor-only-menu',
          'editor_only_page_content',
          'dashicons-edit',
          30
        );
      }
    }
    
    add_action( 'admin_menu', 'my_custom_menu' );
    ?>

7. 实战演练

咱们来做一个实际的例子:创建一个名为 "我的插件设置" 的顶级菜单,并在该菜单下添加两个子菜单:"常规设置" 和 "高级设置"。只有管理员才能访问。

<?php
/*
Plugin Name: My Custom Plugin Settings
Description: Adds a custom settings menu to the WordPress admin.
Version: 1.0
Author: Your Name
*/

// 添加后台菜单
function my_plugin_settings_menu() {
  add_menu_page(
    '我的插件设置',
    '我的插件设置',
    'manage_options',
    'my-plugin-settings',
    'my_plugin_general_settings_page',
    'dashicons-admin-generic',
    80
  );

  add_submenu_page(
    'my-plugin-settings',
    '常规设置',
    '常规设置',
    'manage_options',
    'my-plugin-general-settings',
    'my_plugin_general_settings_page'
  );

  add_submenu_page(
    'my-plugin-settings',
    '高级设置',
    '高级设置',
    'manage_options',
    'my-plugin-advanced-settings',
    'my_plugin_advanced_settings_page'
  );

  // 隐藏 "我的插件设置" 的顶级菜单对应的页面,因为我们只想显示子菜单的内容
  global $submenu;
  if ( isset( $submenu['my-plugin-settings'] ) ) {
    $submenu['my-plugin-settings'][0][0] = null;
  }
}
add_action( 'admin_menu', 'my_plugin_settings_menu' );

// 常规设置页面内容
function my_plugin_general_settings_page() {
  echo '<h1>常规设置</h1>';
  echo '<p>这里是常规设置的内容。</p>';
}

// 高级设置页面内容
function my_plugin_advanced_settings_page() {
  echo '<h1>高级设置</h1>';
  echo '<p>这里是高级设置的内容。</p>';
}
?>

将这段代码保存为 my-plugin-settings.php 文件,并上传到 wp-content/plugins/ 目录下。然后在 WordPress 后台启用这个插件,你就可以在后台菜单中看到 "我的插件设置" 菜单及其子菜单了。

8. 常见问题及解决方案

  • 菜单不显示: 检查权限是否正确,以及菜单别名是否与其他菜单冲突。
  • 菜单位置错乱: 尝试使用 WordPress 预留的菜单位置,或者调整菜单位置的数字。
  • 点击菜单后页面空白: 检查 $function 参数是否正确,以及函数中是否有语法错误。
  • Dashicons 图标不显示: 确保 Dashicons 名称正确,并且已经加载了 Dashicons 样式表。

好了,今天的课程就到这里。希望大家通过今天的学习,能够掌握 admin_menu 钩子的用法,并在 WordPress 后台自由地添加自定义菜单。记住,实践是检验真理的唯一标准,多动手,多尝试,你就能成为真正的 WordPress 后台菜单大师!

下课!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注