分析 WordPress `WP_Post_Type` 类源码:文章类型信息在 `$post_types` 中的存储。

各位程序猿,程序媛,以及对WordPress源码有那么一丢丢好奇的小伙伴们,晚上好!我是今晚的主讲人,代号“代码挖掘机”,很高兴能和大家一起扒一扒WordPress里那些隐藏的宝藏。

今天咱们要挖的宝藏,就是WordPress中负责管理各种文章类型的 WP_Post_Type 类,以及它背后存储文章类型信息的 $post_types 数组。这俩货,可以说是WordPress内容管理的心脏地带。

准备好了吗?系好安全带,让我们开始这场源码探险之旅!

第一站:WP_Post_Type 类 – 文章类型的蓝图

首先,我们需要认识一下 WP_Post_Type 这个类。它就像一个蓝图,定义了文章类型的各种属性和行为。每当我们注册一个新的文章类型(比如“电影”、“书籍”或者你自己想的任何奇奇怪怪的类型),WordPress就会创建一个 WP_Post_Type 类的实例来表示它。

这个类里面都有些啥呢?我们挑几个重要的属性来说说:

  • $name: 文章类型的名称(比如 ‘post’,’page’,’movie’)。这是文章类型的唯一标识符。
  • $args: 一个数组,包含了文章类型的各种参数,比如是否公开显示,是否支持评论,使用哪个菜单图标等等。
  • $label: 文章类型的单数形式标签(比如 ‘Post’)。
  • $labels: 一个数组,包含了文章类型的各种标签,比如“添加新文章”、“编辑文章”等等。这些标签用于在后台界面上显示。
  • $object_type: 一个数组,包含了与此文章类型关联的对象类型(通常是 ‘post’)。
  • $cap: 一个 WP_Post_Type_Capabilities 类的实例,用于管理此文章类型的权限。

为了更直观地理解,我们来看一段简单的代码,演示如何注册一个自定义文章类型“movie”:

function register_movie_post_type() {
  $args = array(
    'public'    => true,
    'label'     => 'Movies',
    'supports'  => array( 'title', 'editor', 'thumbnail' )
  );
  register_post_type( 'movie', $args );
}
add_action( 'init', 'register_movie_post_type' );

这段代码的核心就是 register_post_type() 函数。它接收两个参数:文章类型的名称(’movie’)和包含各种参数的数组 $argsregister_post_type() 内部会创建一个 WP_Post_Type 类的实例,并将 $args 中的信息填充到这个实例的各个属性中。

第二站:$wp_post_types 全局变量 – 文章类型的大本营

现在,问题来了:register_post_type() 创建的 WP_Post_Type 实例,都跑到哪里去了呢? 答案就在 $wp_post_types 这个全局变量里。

$wp_post_types 是一个全局数组,用于存储所有已注册的文章类型。它的键是文章类型的名称(比如 ‘post’,’page’,’movie’),值是对应的 WP_Post_Type 类的实例。

我们可以把它想象成一个巨大的图书馆,每一本书代表一个文章类型,书名就是文章类型的名称,而书的内容就是 WP_Post_Type 实例中存储的各种属性和信息。

global $wp_post_types;

//假设我们已经注册了 'post', 'page', 'movie' 三种文章类型
if ( isset( $wp_post_types['movie'] ) ) {
  $movie_post_type = $wp_post_types['movie'];
  echo "电影文章类型的单数标签是:" . $movie_post_type->label; // 输出:电影文章类型的单数标签是:Movies
}

这段代码演示了如何从 $wp_post_types 数组中获取特定文章类型的信息。通过访问 $wp_post_types['movie'],我们可以得到 ‘movie’ 文章类型对应的 WP_Post_Type 实例,然后就可以访问它的各种属性,比如 $movie_post_type->label

第三站:register_post_type() 的内部运作 – 如何将文章类型添加到大本营

接下来,我们深入 register_post_type() 函数的内部,看看它是如何将文章类型添加到 $wp_post_types 数组中的。

register_post_type() 函数的内部流程大致如下:

  1. 参数验证和处理: 首先,它会验证文章类型的名称是否合法,以及 $args 数组中的参数是否正确。
  2. 创建 WP_Post_Type 实例: 然后,它会创建一个 WP_Post_Type 类的实例,并将文章类型的名称和参数传递给它。
  3. 设置默认值: 接下来,它会根据 $args 数组中的参数,设置 WP_Post_Type 实例的各个属性。如果 $args 中没有指定某些参数,它会使用默认值。
  4. 注册标签: 它会根据 $args 数组中的 ‘labels’ 参数,注册文章类型的各种标签。如果没有指定 ‘labels’ 参数,它会使用默认的标签。
  5. 注册权限: 它会根据 $args 数组中的 ‘capabilities’ 参数,注册文章类型的权限。如果没有指定 ‘capabilities’ 参数,它会使用默认的权限。
  6. 添加到 $wp_post_types 数组: 最后,它会将 WP_Post_Type 实例添加到 $wp_post_types 数组中,并将文章类型的名称作为键。

虽然我们没有直接看到 WP_Post_Type 类的源码,但是通过了解 register_post_type() 函数的内部运作,我们可以更好地理解 WP_Post_Type 实例是如何被创建和存储的。

第四站:get_post_type_object() 函数 – 从大本营中检索文章类型

既然文章类型都存储在 $wp_post_types 数组里了,那么我们如何从中检索特定的文章类型呢? 这就要用到 get_post_type_object() 函数了。

get_post_type_object() 函数接收一个参数:文章类型的名称。它会在 $wp_post_types 数组中查找对应的 WP_Post_Type 实例,并将其返回。如果找不到,则返回 null

$movie_post_type = get_post_type_object( 'movie' );

if ( $movie_post_type ) {
  echo "电影文章类型的描述是:" . $movie_post_type->description;
} else {
  echo "未找到名为 'movie' 的文章类型。";
}

这段代码演示了如何使用 get_post_type_object() 函数获取 ‘movie’ 文章类型的信息。如果找到了 ‘movie’ 文章类型,就可以访问它的各种属性,比如 $movie_post_type->description

第五站:WP_Post_Type_Capabilities 类 – 文章类型的权限管理

前面提到过,WP_Post_Type 类有一个 $cap 属性,它是一个 WP_Post_Type_Capabilities 类的实例。这个类负责管理文章类型的各种权限,比如“编辑文章”、“删除文章”、“发布文章”等等。

WP_Post_Type_Capabilities 类包含以下几个重要的属性:

  • $edit_post: 编辑文章的权限。
  • $read_post: 读取文章的权限。
  • $delete_post: 删除文章的权限。
  • $edit_posts: 编辑所有文章的权限。
  • $edit_others_posts: 编辑他人文章的权限。
  • $publish_posts: 发布文章的权限。
  • $read_private_posts: 读取私有文章的权限。

通过修改这些权限,我们可以控制用户对文章类型的访问和操作。

总结:文章类型信息的存储结构

为了更好地理解文章类型信息的存储结构,我们可以用一个表格来总结一下:

全局变量 描述
$wp_post_types 文章类型名称 (e.g., ‘post’, ‘page’, ‘movie’) WP_Post_Type 类的实例 存储所有已注册文章类型的核心数组。每个文章类型都有一个对应的 WP_Post_Type 实例,包含了该文章类型的各种属性和信息。
WP_Post_Type 实例 属性 (e.g., $name, $args, $label, $labels, $cap) 各种数据类型 (字符串, 数组, WP_Post_Type_Capabilities 实例) 存储特定文章类型的详细信息,包括名称、参数、标签、权限等等。$cap 属性是一个 WP_Post_Type_Capabilities 类的实例,用于管理该文章类型的权限。
WP_Post_Type_Capabilities 实例 属性 (e.g., $edit_post, $read_post, $delete_post) 字符串 (权限名称) 存储特定文章类型的各种权限。每个属性都对应一个权限名称,用于在WordPress的权限系统中进行验证。

一些小技巧和注意事项

  • 不要直接修改 $wp_post_types 数组: 虽然 $wp_post_types 是一个全局变量,但是强烈不建议直接修改它。你应该使用 register_post_type() 函数来注册新的文章类型,或者使用 unregister_post_type() 函数来注销已注册的文章类型。直接修改 $wp_post_types 数组可能会导致不可预测的错误。
  • 使用 get_post_type_object() 函数获取文章类型信息: 不要直接访问 $wp_post_types 数组来获取文章类型信息。你应该使用 get_post_type_object() 函数,它可以确保你获取到的是有效的 WP_Post_Type 实例。
  • 理解文章类型和文章的关系: 文章类型是文章的类别,而文章是文章类型的实例。你可以把文章类型想象成一个类,而文章想象成这个类的对象。
  • 善用 args 参数: 在注册文章类型时,args 参数非常重要。你可以通过 args 参数来控制文章类型的各种行为,比如是否公开显示,是否支持评论,使用哪个菜单图标等等。

总结

好了,今天的源码探险之旅就到此结束了。希望通过今天的讲解,大家对 WordPress 中文章类型的存储方式有了更深入的了解。

我们学习了 WP_Post_Type 类,它是文章类型的蓝图;我们认识了 $wp_post_types 全局变量,它是文章类型的大本营;我们分析了 register_post_type() 函数的内部运作,了解了文章类型是如何被添加到大本营的;我们还学习了 get_post_type_object() 函数,它可以帮助我们从大本营中检索文章类型。

记住,理解 WordPress 源码是成为 WordPress 大神的必经之路。希望大家能够继续深入学习 WordPress 源码,挖掘更多的宝藏!

感谢大家的参与,下次再见!

发表回复

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