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_book ,delete_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 ];
}
让我们一步步解读这段代码:
-
声明全局变量: 函数一开始就声明了全局变量
$wp_post_types
。 这个变量是一个数组,用于存储所有已注册的文章类型的信息。global $wp_post_types; if ( ! is_array( $wp_post_types ) ) { $wp_post_types = array(); }
如果
$wp_post_types
变量还未初始化,则将其初始化为一个空数组。 -
参数验证和处理: 接下来,函数会对传入的参数进行验证和处理,确保参数的有效性。 这部分代码比较复杂,涉及到各种参数的检查和转换,这里不做详细展开。
-
设置默认参数:
$defaults
数组定义了文章类型的默认参数。 如果在$args
参数中没有指定某个参数,则会使用默认值。$defaults = array( 'labels' => array(), 'description' => '', 'public' => false, // ... 其他参数 );
-
合并参数:
wp_parse_args()
函数用于将用户传入的参数$args
与默认参数$defaults
合并。 这样可以确保所有的参数都有值,即使没有在$args
中指定。$args = wp_parse_args( $args, $defaults );
-
创建
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
数组中。 -
返回注册结果: 最后,函数返回新创建的
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 构建各种各样的网站了。
希望今天的讲座对大家有所帮助! 感谢大家的收听,我们下次再见!