阐述 `register_post_type()` 函数的源码,解释它是如何将文章类型信息添加到 `Array` 全局变量的?

WordPress 文章类型注册机制剖析:register_post_type() 函数源码解读

各位观众,晚上好!我是今天的主讲人,咱们今天的主题是 WordPress 的核心机制之一:文章类型的注册。 我们都知道,WordPress 不仅仅是写博客的工具,还能构建各种各样的网站,比如电商、论坛等等。 这背后的功臣之一就是文章类型(Post Types)。 WordPress 通过文章类型来区分不同类型的内容,例如文章、页面、自定义文章类型等等。

今天,我们要深入挖掘 register_post_type() 这个函数,看看它是如何将文章类型的信息添加到 WordPress 的全局变量中,最终实现对文章类型的管理和展示的。 准备好了吗?让我们开始吧!

文章类型:不止于文章

首先,让我们明确一下文章类型的概念。 在 WordPress 中,一切皆内容。 无论是博客文章、静态页面、产品信息,还是自定义的活动、课程等等,都可以被视为一种内容类型。 文章类型就是对这些内容类型的分类和定义。

默认情况下,WordPress 提供了几种内置的文章类型,包括:

  • post: 普通文章,用于发布博客内容。
  • page: 页面,用于创建静态页面,如“关于我们”、“联系方式”等。
  • attachment: 附件,用于存储上传的媒体文件,如图片、视频等。

除了内置的文章类型,WordPress 还允许我们注册自定义文章类型,以满足各种各样的需求。 比如,我们可以创建一个名为 book 的自定义文章类型,用于管理图书信息;或者创建一个名为 event 的文章类型,用于管理活动信息。

register_post_type():文章类型注册的核心

register_post_type() 函数是 WordPress 中注册文章类型的核心函数。 它的作用是将文章类型的名称、标签、功能等信息注册到 WordPress 系统中,使其能够被识别和管理。

让我们来看一下 register_post_type() 函数的基本语法:

register_post_type( string $post_type, array|string $args = array() )
  • $post_type: 必需参数,文章类型的名称。 只能包含小写字母、数字和下划线,且长度不能超过 20 个字符。
  • $args: 可选参数,一个包含文章类型参数的数组,用于定义文章类型的各种属性和功能。

$args 参数可以包含很多选项,用于控制文章类型的各种行为,包括:

参数 类型 描述
labels array 用于定义文章类型的各种标签,如“添加新文章”、“编辑文章”等。
description string 文章类型的描述信息。
public bool 是否公开该文章类型。 如果设置为 true,则该文章类型会在前端显示,并可以通过 URL 访问。
hierarchical bool 是否具有层级关系。 如果设置为 true,则该文章类型可以像页面一样具有父子关系。
supports array 用于指定文章类型支持的功能,如标题、正文、摘要、特色图像等。
taxonomies array 用于指定文章类型关联的分类法,如分类、标签等。
has_archive bool 是否启用文章类型的存档页面。 如果设置为 true,则 WordPress 会自动创建一个存档页面,用于显示该文章类型的所有文章。
rewrite array 用于自定义文章类型的 URL 重写规则。
menu_position int 在后台菜单中显示的位置。
menu_icon string 在后台菜单中显示的图标。
capability_type string or array 用于定义文章类型的权限类型。 可以是单个字符串,也可以是包含两个字符串的数组(例如 array('book', 'books'),分别代表单数和复数形式)。 它会影响到 WordPress 如何生成文章类型的权限,例如 edit_bookdelete_books 等。

源码剖析:register_post_type() 的内部运作

接下来,让我们深入 register_post_type() 函数的源码,看看它是如何工作的。

function register_post_type( $post_type, $args = array() ) {
    global $wp_post_types;

    if ( ! is_array( $wp_post_types ) ) {
        $wp_post_types = array();
    }

    // 参数验证和处理...

    $defaults = array(
        'labels' => array(),
        'description' => '',
        'public' => false,
        'exclude_from_search' => false,
        'publicly_queryable' => null,
        'show_ui' => null,
        'show_in_menu' => null,
        'show_in_nav_menus' => null,
        'show_in_admin_bar' => null,
        'menu_position' => null,
        'menu_icon' => null,
        'capability_type' => 'post',
        'capabilities' => array(),
        'map_meta_cap' => false,
        'hierarchical' => false,
        'supports' => array(),
        'register_meta_box_cb' => '',
        'taxonomies' => array(),
        'has_archive' => false,
        'rewrite' => true,
        'query_var' => true,
        'can_export' => true,
        'delete_with_user' => null,
        '_builtin' => false,
        '_edit_link' => 'post.php?post=%d',
    );

    $args = wp_parse_args( $args, $defaults );

    // 创建一个 WP_Post_Type 对象
    $wp_post_types[ $post_type ] = new WP_Post_Type( $post_type, $args );

    // 返回注册结果
    return $wp_post_types[ $post_type ];
}

让我们一步步解读这段代码:

  1. 声明全局变量: 函数一开始就声明了全局变量 $wp_post_types。 这个变量是一个数组,用于存储所有已注册的文章类型的信息。

    global $wp_post_types;
    
    if ( ! is_array( $wp_post_types ) ) {
        $wp_post_types = array();
    }

    如果 $wp_post_types 变量还未初始化,则将其初始化为一个空数组。

  2. 参数验证和处理: 接下来,函数会对传入的参数进行验证和处理,确保参数的有效性。 这部分代码比较复杂,涉及到各种参数的检查和转换,这里不做详细展开。

  3. 设置默认参数: $defaults 数组定义了文章类型的默认参数。 如果在 $args 参数中没有指定某个参数,则会使用默认值。

    $defaults = array(
        'labels' => array(),
        'description' => '',
        'public' => false,
        // ... 其他参数
    );
  4. 合并参数: wp_parse_args() 函数用于将用户传入的参数 $args 与默认参数 $defaults 合并。 这样可以确保所有的参数都有值,即使没有在 $args 中指定。

    $args = wp_parse_args( $args, $defaults );
  5. 创建 WP_Post_Type 对象: 这是最关键的一步。 函数会创建一个 WP_Post_Type 对象,并将文章类型的信息存储在该对象中。

    $wp_post_types[ $post_type ] = new WP_Post_Type( $post_type, $args );

    WP_Post_Type 是一个类,用于表示一个文章类型。 它的构造函数会接收文章类型的名称和参数,并将这些信息存储在对象的属性中。

    然后,将这个 WP_Post_Type 对象以文章类型名称 $post_type 为键名,存储到全局变量 $wp_post_types 数组中。

  6. 返回注册结果: 最后,函数返回新创建的 WP_Post_Type 对象。

    return $wp_post_types[ $post_type ];

WP_Post_Type 类:文章类型的容器

WP_Post_Type 类是文章类型的容器,它存储了文章类型的所有信息。 让我们来看一下 WP_Post_Type 类的基本结构:

class WP_Post_Type {
    public $name;
    public $label;
    public $labels;
    public $description;
    public $public;
    public $exclude_from_search;
    public $publicly_queryable;
    public $show_ui;
    public $show_in_menu;
    public $show_in_nav_menus;
    public $show_in_admin_bar;
    public $menu_position;
    public $menu_icon;
    public $capability_type;
    public $capabilities;
    public $map_meta_cap;
    public $hierarchical;
    public $supports;
    public $register_meta_box_cb;
    public $taxonomies;
    public $has_archive;
    public $rewrite;
    public $query_var;
    public $can_export;
    public $delete_with_user;
    public $_builtin;
    public $_edit_link;

    public function __construct( $post_type, $args = array() ) {
        $this->name = $post_type;

        // 处理参数,将参数赋值给对象的属性
        foreach ( $args as $key => $value ) {
            $this->$key = $value;
        }

        // ... 其他初始化操作
    }

    // ... 其他方法
}

WP_Post_Type 类的属性对应于 register_post_type() 函数的 $args 参数。 它的构造函数会将 $args 参数中的值赋值给对象的属性,从而将文章类型的信息存储在对象中。

示例:注册一个自定义文章类型

让我们通过一个简单的例子来演示如何使用 register_post_type() 函数注册一个自定义文章类型。

function register_book_post_type() {
    $args = array(
        'labels' => array(
            'name' => '书籍',
            'singular_name' => '书籍',
        ),
        'public' => true,
        'has_archive' => true,
        'supports' => array( 'title', 'editor', 'thumbnail' ),
        'menu_icon' => 'dashicons-book',
    );

    register_post_type( 'book', $args );
}

add_action( 'init', 'register_book_post_type' );

这段代码会注册一个名为 book 的自定义文章类型,用于管理图书信息。

  • labels: 定义了文章类型的标签,包括名称和单数名称。
  • public: 设置为 true,表示该文章类型是公开的。
  • has_archive: 设置为 true,表示启用文章类型的存档页面。
  • supports: 指定文章类型支持标题、正文和特色图像功能。
  • menu_icon: 设置在后台菜单中显示的图标为书籍图标。

add_action( 'init', 'register_book_post_type' ) 这行代码将 register_book_post_type() 函数绑定到 init 钩子上。 init 钩子在 WordPress 初始化时触发,因此 register_book_post_type() 函数会在 WordPress 初始化时被调用,从而注册 book 文章类型。

如何获取已注册的文章类型?

既然我们知道文章类型的信息都存储在全局变量 $wp_post_types 中,那么如何获取这些信息呢?

WordPress 提供了 get_post_types() 函数,用于获取所有已注册的文章类型。

$post_types = get_post_types();

print_r( $post_types );

这段代码会输出一个包含所有已注册文章类型名称的数组。

如果你只想获取某个特定文章类型的信息,可以使用 get_post_type_object() 函数。

$book_post_type = get_post_type_object( 'book' );

print_r( $book_post_type );

这段代码会输出 book 文章类型的 WP_Post_Type 对象,包含了该文章类型的所有信息。

总结

今天,我们深入探讨了 WordPress 中文章类型的注册机制,详细解读了 register_post_type() 函数的源码。 我们了解了 register_post_type() 函数如何将文章类型的信息添加到全局变量 $wp_post_types 中,以及如何使用 WP_Post_Type 类来存储文章类型的信息。 掌握了这些知识,你就可以更加灵活地使用 WordPress 构建各种各样的网站了。

希望今天的讲座对大家有所帮助! 感谢大家的收听,我们下次再见!

发表回复

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