嘿,各位代码狂魔,欢迎来到今天的WordPress源码解剖课堂!今天我们要攻克的堡垒是register_taxonomy()函数,看看它如何把分类法信息塞进那个神秘的全局变量$wp_taxonomies里。准备好你的咖啡,我们开始吧!
开场白:分类法的江湖地位
在WordPress的世界里,分类法(Taxonomy)就像一棵树的枝干,帮助我们把文章、页面、自定义文章类型组织得井井有条。有了分类法,内容才不会像无头苍蝇一样乱飞,用户也能更容易地找到自己想要的信息。而register_taxonomy()函数,就是那把锋利的斧头,帮我们砍出这些枝干。
第一幕:register_taxonomy()函数概览
首先,我们来认识一下register_taxonomy()函数的基本结构。它长这样:
function register_taxonomy( string $taxonomy, string|array $object_type, array|string $args = array() ): WP_Taxonomy|WP_Error {
// 函数体内容
}
看起来是不是很眼熟?这货接受三个参数:
$taxonomy:分类法的名称,比如’category’,’post_tag’,或者你自己定义的’genre’。这就像给分类法起个响亮的名号,以后就靠它行走江湖了。$object_type:与分类法相关联的文章类型,可以是’post’,’page’,或者你自定义的’movie’。这就像告诉分类法,它是哪个帮派的,以后只管这些文章类型。$args:一个数组,包含各种各样的选项,控制分类法的行为,比如是否显示在管理界面,是否允许层级关系等等。这就像给分类法定制装备,让它更强大。
而它的返回值,要么是一个WP_Taxonomy对象,代表成功注册的分类法,要么是一个WP_Error对象,告诉你哪里出了问题。
第二幕:源码解读,抽丝剥茧
接下来,我们深入register_taxonomy()的源码,看看它是如何一步步工作的:
function register_taxonomy( string $taxonomy, string|array $object_type, array|string $args = array() ): WP_Taxonomy|WP_Error {
global $wp_taxonomies;
// 1. 参数校验和整理
if ( ! is_string( $taxonomy ) ) {
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must be strings.' ) );
}
if ( strlen( $taxonomy ) > 32 ) {
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must not exceed 32 characters in length.' ) );
}
$taxonomy = sanitize_key( $taxonomy );
if ( empty( $taxonomy ) ) {
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must not be empty.' ) );
}
if ( ! is_string( $object_type ) && ! is_array( $object_type ) ) {
return new WP_Error( 'invalid_object_type', __( 'Object types must be strings or arrays.' ) );
}
// 2. 默认参数设置
$default_args = array(
'labels' => array(),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'show_admin_column' => false,
'hierarchical' => false,
'query_var' => $taxonomy,
'rewrite' => true,
'capabilities' => array(),
'meta_box_cb' => null,
'show_admin_column' => false,
'description' => '',
'sort' => null,
'_builtin' => false,
);
$args = wp_parse_args( $args, $default_args );
// 3. 创建 WP_Taxonomy 对象
$wp_taxonomy = new WP_Taxonomy( $taxonomy, $object_type, $args );
// 4. 注册分类法到全局变量 $wp_taxonomies
$wp_taxonomies[ $taxonomy ] = $wp_taxonomy;
// 5. 关联分类法到文章类型
if ( is_array( $object_type ) ) {
foreach ( $object_type as $type ) {
register_taxonomy_for_object_type( $taxonomy, $type );
}
} else {
register_taxonomy_for_object_type( $taxonomy, $object_type );
}
// 6. 返回 WP_Taxonomy 对象
return $wp_taxonomy;
}
让我们把这段代码分成几个部分来解读:
1. 参数校验和整理
首先,函数会检查传入的参数是否合法,比如分类法名称是否是字符串,长度是否超过32个字符,是否为空等等。如果发现问题,会返回一个WP_Error对象,告诉你哪里出错了。
if ( ! is_string( $taxonomy ) ) {
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must be strings.' ) );
}
if ( strlen( $taxonomy ) > 32 ) {
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must not exceed 32 characters in length.' ) );
}
$taxonomy = sanitize_key( $taxonomy );
if ( empty( $taxonomy ) ) {
return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must not be empty.' ) );
}
if ( ! is_string( $object_type ) && ! is_array( $object_type ) ) {
return new WP_Error( 'invalid_object_type', __( 'Object types must be strings or arrays.' ) );
}
这些检查就像保安一样,确保只有合格的分类法才能进入WordPress的殿堂。sanitize_key()函数会将分类法名称转换成安全的格式,防止潜在的安全问题。
2. 默认参数设置
接下来,函数会设置一些默认参数,如果没有在$args参数中指定,就使用这些默认值。
$default_args = array(
'labels' => array(),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'show_admin_column' => false,
'hierarchical' => false,
'query_var' => $taxonomy,
'rewrite' => true,
'capabilities' => array(),
'meta_box_cb' => null,
'show_admin_column' => false,
'description' => '',
'sort' => null,
'_builtin' => false,
);
$args = wp_parse_args( $args, $default_args );
wp_parse_args()函数会将用户传入的$args参数和默认参数合并,如果用户指定了某个参数,就使用用户的值,否则使用默认值。这就像餐厅里的自助餐,你可以选择自己喜欢的菜,如果没有,就吃厨师准备好的。
这里列出一些重要的参数:
| 参数名 | 描述 | 默认值 |
|---|---|---|
labels |
一个数组,包含各种标签,用于在管理界面显示,比如’name’,’singular_name’,’search_items’等等。 | 空数组 |
public |
是否公开分类法,如果为true,则可以在前台页面显示。 | true |
show_ui |
是否在管理界面显示分类法。 | true |
show_in_menu |
是否在管理菜单中显示分类法。 | true |
hierarchical |
是否允许层级关系,如果为true,则可以像分类目录一样有父子关系,如果为false,则像标签一样是扁平的。 | false |
query_var |
用于查询分类法的查询变量,默认为分类法的名称。 | $taxonomy |
rewrite |
是否启用URL重写,如果为true,则可以使用更友好的URL,比如/genre/action而不是/?genre=action。 |
true |
show_admin_column |
是否在文章列表页面显示分类法列,方便快速编辑。 | false |
3. 创建 WP_Taxonomy 对象
现在,所有的参数都准备好了,函数会创建一个WP_Taxonomy对象,把这些参数都塞进去。
$wp_taxonomy = new WP_Taxonomy( $taxonomy, $object_type, $args );
WP_Taxonomy类是WordPress专门用来表示分类法的,它包含了分类法的所有信息,比如名称,关联的文章类型,各种选项等等。这就像给分类法颁发了一个身份证,证明它是一个合法的公民。
4. 注册分类法到全局变量 $wp_taxonomies
关键时刻到了!函数会将刚刚创建的WP_Taxonomy对象注册到全局变量$wp_taxonomies中。
global $wp_taxonomies;
$wp_taxonomies[ $taxonomy ] = $wp_taxonomy;
$wp_taxonomies是一个全局数组,存储了所有注册的分类法。在这里,函数会将分类法的名称作为键,WP_Taxonomy对象作为值,存储到这个数组中。
这就像把分类法的名字刻在名人墙上,让WordPress知道它的存在。以后,WordPress就可以通过这个全局变量来访问和管理这些分类法了。
5. 关联分类法到文章类型
接下来,函数会将分类法和文章类型关联起来,告诉WordPress,这个分类法是属于哪个文章类型的。
if ( is_array( $object_type ) ) {
foreach ( $object_type as $type ) {
register_taxonomy_for_object_type( $taxonomy, $type );
}
} else {
register_taxonomy_for_object_type( $taxonomy, $object_type );
}
register_taxonomy_for_object_type()函数会将分类法和文章类型的关系存储起来,方便以后查询和使用。
这就像给分类法贴上标签,告诉大家它是属于哪个帮派的。以后,WordPress就可以根据这些标签来过滤和显示文章。
6. 返回 WP_Taxonomy 对象
最后,函数会返回刚刚创建的WP_Taxonomy对象,方便调用者使用。
return $wp_taxonomy;
这就像把分类法的身份证还给它,让它可以自由地行走江湖了。
第三幕:$wp_taxonomies 变量的结构
现在,让我们来仔细看看$wp_taxonomies变量的结构。它是一个全局数组,以分类法名称为键,WP_Taxonomy对象为值。
global $wp_taxonomies;
print_r($wp_taxonomies);
// 输出结果示例:
Array
(
[category] => WP_Taxonomy Object
(
[name] => category
[object_type] => Array
(
[0] => post
)
[label] => 分类目录
[labels] => Array
(
[name] => 分类目录
[singular_name] => 分类目录
[search_items] => 搜索分类目录
[all_items] => 所有分类目录
[parent_item] => 父级分类目录
[parent_item_colon] => 父级分类目录:
[edit_item] => 编辑分类目录
[view_item] => 查看分类目录
[update_item] => 更新分类目录
[add_new_item] => 添加新分类目录
[new_item_name] => 新分类目录名称
[separate_items_with_commas] => 用逗号分隔分类目录
[add_or_remove_items] => 添加或移除分类目录
[choose_from_most_used] => 从最常用的分类目录中选择
[not_found] => 未找到分类目录。
[no_terms] => 没有分类目录。
[menu_name] => 分类目录
[filter_by_item] => 按分类目录筛选
[items_list_navigation] => 分类目录列表导航
[items_list] => 分类目录列表
[most_used] => Most Used
[back_to_items] => ← Back to Categories
[item] => Category
[new_item] => New Category
)
[description] =>
[public] => 1
[show_ui] => 1
[show_in_menu] => 1
[show_in_nav_menus] => 1
[show_tagcloud] => 1
[show_in_quick_edit] =>
[show_admin_column] => 1
[hierarchical] => 1
[update_count_callback] => _update_post_term_count
[query_var] => category
[rewrite] => Array
(
[slug] => category
[with_front] => 1
[hierarchical] =>
[ep_mask] => 8192
[feed] =>
[pages] =>
)
[capabilities] => Array
(
[manage_terms] => manage_categories
[edit_terms] => edit_categories
[delete_terms] => delete_categories
[assign_terms] => assign_categories
)
[_builtin] => 1
[_edit_link] => edit-tags.php?action=edit&taxonomy=
)
[post_tag] => WP_Taxonomy Object
(
// ... 更多分类法
)
)
可以看到,$wp_taxonomies数组中存储了所有的分类法,每个分类法都是一个WP_Taxonomy对象,包含了分类法的各种信息。
第四幕:实战演练,代码示例
现在,让我们通过一个代码示例来演示如何使用register_taxonomy()函数:
function register_movie_genre() {
$labels = array(
'name' => _x( '电影类型', 'taxonomy general name' ),
'singular_name' => _x( '电影类型', 'taxonomy singular name' ),
'search_items' => __( '搜索电影类型' ),
'all_items' => __( '所有电影类型' ),
'parent_item' => __( '父级电影类型' ),
'parent_item_colon' => __( '父级电影类型:' ),
'edit_item' => __( '编辑电影类型' ),
'update_item' => __( '更新电影类型' ),
'add_new_item' => __( '添加新电影类型' ),
'new_item_name' => __( '新电影类型名称' ),
'menu_name' => __( '电影类型' ),
);
$args = array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'genre' ),
);
register_taxonomy( 'genre', 'movie', $args );
}
add_action( 'init', 'register_movie_genre', 0 );
这段代码定义了一个名为register_movie_genre()的函数,用于注册一个名为’genre’的分类法,用于管理电影类型。
- 首先,定义了一个
$labels数组,包含了各种标签,用于在管理界面显示。 - 然后,定义了一个
$args数组,包含了各种选项,比如是否允许层级关系,是否在管理界面显示等等。 - 最后,调用
register_taxonomy()函数,将分类法注册到WordPress中。
add_action( 'init', 'register_movie_genre', 0 );这行代码会在WordPress初始化时调用register_movie_genre()函数,确保分类法在第一时间被注册。
这样,我们就成功地创建了一个自定义分类法’genre’,用于管理电影类型。你可以在管理界面的“文章”菜单下找到“电影类型”菜单,添加和管理电影类型。
第五幕:总结与思考
今天,我们深入解读了register_taxonomy()函数的源码,了解了它是如何把分类法信息添加到$wp_taxonomies全局变量中的。
总结一下:
register_taxonomy()函数接受三个参数:分类法名称,文章类型,选项数组。- 函数会首先校验参数,然后设置默认参数。
- 函数会创建一个
WP_Taxonomy对象,把参数都塞进去。 - 函数会将
WP_Taxonomy对象注册到$wp_taxonomies全局变量中。 - 函数会将分类法和文章类型关联起来。
- 函数会返回
WP_Taxonomy对象。
$wp_taxonomies变量是一个全局数组,存储了所有注册的分类法,每个分类法都是一个WP_Taxonomy对象。
通过今天的学习,相信你对WordPress的分类法机制有了更深入的了解。以后,你就可以更加灵活地使用register_taxonomy()函数,创建自定义分类法,管理你的内容了。
希望今天的讲座对你有所帮助。下次再见!