阐述 WordPress `WP_Screen` 类的源码:它是如何管理后台页面的上下文和元数据框的。

各位,今天咱们来聊聊 WordPress 后台的“幕后老板”—— WP_Screen 类。这家伙负责管理后台页面的上下文,就像一个经验老道的管家,知道哪个房间(页面)该摆什么家具(元数据框),谁能进哪个房间(权限),等等。

咱们先来热个身,看看 WP_Screen 类的基本结构,然后深入了解它是如何管理上下文和元数据框的。

WP_Screen 类:后台页面的总管

WP_Screen 类位于 wp-includes/class-wp-screen.php 文件中。它是一个抽象类,但我们通常会用到它的实例,这些实例代表着 WordPress 后台的每个页面。

先来看看它的核心属性(成员变量):

属性名 数据类型 描述
$id string 页面的唯一ID,例如 edit-post(文章列表页面)、post(文章编辑页面)、dashboard(仪表盘)等。
$taxonomy string 如果是分类法页面,则保存分类法的名称,例如 categorypost_tag
$post_type string 如果是文章类型页面,则保存文章类型的名称,例如 postpageproduct
$base string 页面的基本ID,通常是 $id 的一部分。例如,edit-post$baseedit
$action string 当前执行的操作,例如 addedit
$parent_base string 父页面的基本ID,用于构建菜单结构。
$parent_file string 父页面的文件路径,用于构建菜单结构。
$screen_icon string 页面的图标,通常是 CSS 类名。
$columns int 如果是列表页面,则表示列表显示的列数。
$available bool 页面是否可用。
$help_tabs array 帮助标签页的数组。
$help_sidebar string 帮助侧边栏的内容。
$options array 页面选项,例如每页显示的文章数量。
$_meta_boxes array 关键的属性,存储着页面上的元数据框。这是一个多维数组,按照 context (例如 ‘normal’, ‘advanced’, ‘side’) 和 priority (例如 ‘high’, ‘core’, ‘default’, ‘low’) 排序。

WP_Screen 实例的创建:找到你的页面

要获取 WP_Screen 实例,可以使用 get_current_screen() 函数。这个函数会返回当前页面的 WP_Screen 对象。如果没有找到,会返回 null

$screen = get_current_screen();

if ( $screen ) {
  // 输出当前页面的 ID
  echo '当前页面 ID: ' . $screen->id . '<br>';

  // 输出当前页面类型
  echo '当前页面基类: ' . $screen->base . '<br>';

  // 检查是否是文章编辑页面
  if ( $screen->id === 'post' ) {
    echo '你正在编辑文章!';
  }
} else {
  echo '没有找到当前页面。';
}

这段代码首先尝试获取当前页面的 WP_Screen 对象。如果成功获取,它会输出页面的 ID 和基类。然后,它会检查是否是文章编辑页面,如果是,则输出一条消息。

WP_Screen 如何管理上下文:页面信息的“数据库”

WP_Screen 类就像一个页面信息的“数据库”,它存储了页面的各种属性,例如 ID、类型、操作等等。这些属性构成了页面的上下文。

WP_Screen 实例的属性在页面加载时被设置,通常是在 WordPress 的 admin_menu 钩子中。 WordPress 会根据当前请求的 URL 和其他信息,确定当前页面的类型,并创建一个对应的 WP_Screen 实例。

例如,当你访问文章编辑页面时,WordPress 会创建一个 WP_Screen 实例,并将 $id 设置为 post$post_type 设置为 post$action 设置为 editadd(取决于你是在编辑现有文章还是创建新文章)。

WP_Screen 如何管理元数据框:家具的摆放艺术

WP_Screen 类最重要的一项任务就是管理元数据框(meta boxes)。元数据框是 WordPress 后台页面上用于输入和编辑数据的区域,例如文章的标题、内容、摘要、分类、标签等等。

WP_Screen 使用 $_meta_boxes 属性来存储元数据框的信息。这是一个多维数组,按照 contextpriority 排序。

  • Context (上下文): 指定元数据框应该显示在页面的哪个区域。常见的上下文包括:

    • normal: 正常区域,通常显示在编辑器下方。
    • advanced: 高级区域,通常显示在正常区域下方,可以折叠。
    • side: 侧边栏区域,通常显示在页面的右侧。
  • Priority (优先级): 指定元数据框在同一个上下文中显示的顺序。常见的优先级包括:

    • high: 高优先级,显示在顶部。
    • core: 核心优先级,显示在顶部,通常用于 WordPress 核心功能。
    • default: 默认优先级,显示在中间。
    • low: 低优先级,显示在底部。

添加元数据框:给页面添置家具

要添加元数据框,可以使用 add_meta_box() 函数。这个函数会将元数据框的信息添加到 $_meta_boxes 数组中。

function my_add_meta_box() {
  add_meta_box(
    'my_meta_box_id',       // ID
    '我的元数据框',           // 标题
    'my_meta_box_callback', // 回调函数
    'post',               // 页面(文章类型)
    'side',               // 上下文
    'high'                // 优先级
  );
}
add_action( 'add_meta_boxes', 'my_add_meta_box' );

function my_meta_box_callback( $post ) {
  // 在这里输出元数据框的内容
  echo '<label for="my_meta_field">我的字段:</label>';
  echo '<input type="text" id="my_meta_field" name="my_meta_field" value="' . get_post_meta( $post->ID, 'my_meta_field', true ) . '">';
}

这段代码首先定义了一个名为 my_add_meta_box() 的函数,这个函数使用 add_meta_box() 函数添加一个元数据框。

  • 'my_meta_box_id' 是元数据框的唯一 ID。
  • '我的元数据框' 是元数据框的标题。
  • 'my_meta_box_callback' 是一个回调函数,用于输出元数据框的内容。
  • 'post' 指定元数据框应该显示在文章编辑页面。
  • 'side' 指定元数据框应该显示在侧边栏区域。
  • 'high' 指定元数据框应该具有高优先级。

然后,代码定义了一个名为 my_meta_box_callback() 的函数,这个函数输出一个文本输入框。

最后,代码使用 add_action() 函数将 my_add_meta_box() 函数添加到 add_meta_boxes 钩子中。这意味着当 WordPress 加载文章编辑页面时,my_add_meta_box() 函数会被调用,从而添加元数据框。

add_meta_box() 函数的详细解析:

function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
    global $wp_meta_boxes;

    $screen = convert_to_screen( $screen );

    if ( ! is_string( $id ) ) {
        return;
    }

    $id = sanitize_key( $id );

    if ( empty( $title ) ) {
        return;
    }

    $accepted_contexts = array( 'normal', 'advanced', 'side' );
    if ( empty( $context ) || ! in_array( $context, $accepted_contexts, true ) ) {
        $context = 'advanced';
    }

    $accepted_priorities = array( 'high', 'core', 'default', 'low' );
    if ( empty( $priority ) || ! in_array( $priority, $accepted_priorities, true ) ) {
        $priority = 'default';
    }

    $new_box = array(
        'id'            => $id,
        'title'         => $title,
        'callback'      => $callback,
        'args'          => $callback_args,
        'screen'        => $screen,
        'context'       => $context,
        'priority'      => $priority,
    );

    $wp_meta_boxes[ $screen->id ][ $context ][ $priority ][ $id ] = $new_box;

    return;
}
  • $id: 元数据框的ID,必须是唯一的。
  • $title: 元数据框的标题。
  • $callback: 用于显示元数据框内容的函数。这个函数会接收一个 $post 对象作为参数。
  • $screen: 元数据框应该显示在哪个页面上。可以是文章类型、页面 ID,或者是 WP_Screen 对象。如果为 null,则会显示在所有页面上。
  • $context: 元数据框的上下文(normal, advanced, side)。
  • $priority: 元数据框的优先级(high, core, default, low)。
  • $callback_args: 传递给回调函数的参数。

移除元数据框:给房间腾地方

如果你想移除某个元数据框,可以使用 remove_meta_box() 函数。

function my_remove_meta_box() {
  remove_meta_box( 'postexcerpt', 'post', 'normal' ); // 移除文章摘要元数据框
}
add_action( 'add_meta_boxes', 'my_remove_meta_box' );

这段代码会移除文章编辑页面上,位于 normal 上下文中的 postexcerpt(文章摘要)元数据框。

remove_meta_box() 函数的详细解析:

function remove_meta_box( $id, $screen, $context ) {
    global $wp_meta_boxes;

    $screen = convert_to_screen( $screen );

    unset( $wp_meta_boxes[ $screen->id ][ $context ]['high'][ $id ] );
    unset( $wp_meta_boxes[ $screen->id ][ $context ]['core'][ $id ] );
    unset( $wp_meta_boxes[ $screen->id ][ $context ]['default'][ $id ] );
    unset( $wp_meta_boxes[ $screen->id ][ $context ]['low'][ $id ] );

    return;
}
  • $id: 要移除的元数据框的 ID。
  • $screen: 元数据框所在的页面。可以是文章类型、页面 ID,或者是 WP_Screen 对象。
  • $context: 元数据框的上下文(normal, advanced, side)。

动态控制元数据框:更高级的家具摆放技巧

有时候,你需要根据某些条件来动态控制元数据框的显示。例如,你可能只想在特定文章类型或特定用户角色下显示某个元数据框。

你可以使用 add_meta_boxes 钩子和 get_current_screen() 函数来实现这个功能。

function my_conditional_meta_box() {
  $screen = get_current_screen();

  if ( $screen && $screen->id === 'post' && $_GET['post'] ) { // 确保在文章编辑页面且有文章 ID
    $post_id = $_GET['post'];
    $post_type = get_post_type( $post_id );

    if ( $post_type === 'my_custom_post_type' ) {
      add_meta_box(
        'my_conditional_meta_box_id',
        '自定义文章类型的元数据框',
        'my_meta_box_callback',
        'my_custom_post_type',
        'normal',
        'default'
      );
    } else {
         remove_meta_box( 'my_conditional_meta_box_id', 'post', 'normal' ); // 移除,防止在其他文章类型显示
    }
  }
}
add_action( 'add_meta_boxes', 'my_conditional_meta_box' );

这段代码首先获取当前页面的 WP_Screen 对象,然后检查是否是文章编辑页面,并且存在文章 ID。如果是,它会获取文章类型,并检查是否是 my_custom_post_type。如果是,它会添加一个元数据框。如果不是,则会移除该元数据框(如果之前添加过)。

清理元数据框:保持房间整洁

WordPress 默认会添加一些元数据框,你可能不需要它们。你可以使用 add_meta_boxes 钩子和 remove_meta_box() 函数来清理这些元数据框。

function my_remove_default_meta_boxes() {
  remove_meta_box( 'postcustom', 'post', 'normal' );   // 移除自定义字段元数据框
  remove_meta_box( 'postexcerpt', 'post', 'normal' );  // 移除摘要元数据框
  remove_meta_box( 'commentstatusdiv', 'post', 'normal' ); // 移除评论状态元数据框
  remove_meta_box( 'trackbacksdiv', 'post', 'normal' );  // 移除引用元数据框
  remove_meta_box( 'slugdiv', 'post', 'normal' );       // 移除别名元数据框
  remove_meta_box( 'authordiv', 'post', 'normal' );      // 移除作者元数据框
}
add_action( 'add_meta_boxes', 'my_remove_default_meta_boxes' );

这段代码会移除文章编辑页面上的一些默认元数据框。

总结:WP_Screen 的威力

WP_Screen 类是 WordPress 后台页面的核心,它负责管理页面的上下文和元数据框。通过 WP_Screen 类,你可以:

  • 获取当前页面的信息。
  • 添加、移除和动态控制元数据框。
  • 清理不需要的元数据框。
  • 根据用户角色或文章类型等条件,显示不同的元数据框。

掌握了 WP_Screen 类,你就可以更好地控制 WordPress 后台页面的布局和功能,为用户提供更友好的编辑体验。

高级应用:自定义页面选项和帮助标签

除了管理元数据框,WP_Screen 类还可以用来自定义页面选项和帮助标签。

  • 页面选项 (Screen Options): 允许用户自定义页面上显示的内容和数量。例如,在文章列表页面,用户可以选择每页显示的文章数量,以及显示哪些列。

  • 帮助标签 (Help Tabs): 为用户提供页面相关的帮助信息。

这里因为篇幅限制,就不展开详细讲解了。但是你可以使用 $screen->add_option()$screen->add_help_tab() 方法来添加自定义的页面选项和帮助标签。

总而言之,WP_Screen 类是一个非常强大的工具,可以让你更好地控制 WordPress 后台。 希望今天的讲解能够帮助你理解 WP_Screen 类的原理和使用方法。

发表回复

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