大家好!欢迎来到今天的“WordPress 分类法解剖课”。 今天咱们要深入到 WordPress 的心脏,扒一扒 register_taxonomy()
这个老伙计的底裤,看看它究竟是如何把分类法的信息偷偷塞到全局变量 Array
里的。准备好了吗?系好安全带,咱们要开始了!
第一幕:register_taxonomy()
的前世今生
register_taxonomy()
函数,顾名思义,就是用来注册分类法的。 咱们先来回忆一下它的基本用法:
register_taxonomy(
string $taxonomy,
string|array $object_type,
array $args = array()
);
$taxonomy
: 分类法的名称,比如 ‘category’ (分类) 或者 ‘post_tag’ (标签)。$object_type
: 与分类法关联的对象类型,比如 ‘post’ (文章) 或者 ‘page’ (页面)。$args
: 一个包含各种配置选项的数组,比如是否是分层结构 (hierarchical)、是否显示在菜单中等等。
第二幕:全局变量,幕后黑手
WordPress 的全局变量,就像一个巨大的公共储物柜,各种信息都往里塞。 而 register_taxonomy()
主要涉及的全局变量有:
$wp_taxonomies
: 这是一个数组,存储着所有已注册的分类法对象。每个分类法都以其名称作为键,对应一个WP_Taxonomy
类的实例。$wp_object_types
: 也是一个数组,存储了分类法与对象类型的关系。这个全局变量比较少直接看到,但内部起到关键作用。
第三幕:源码探秘,抽丝剥茧
现在,让我们深入到 register_taxonomy()
的源码中,看看它是如何操作这些全局变量的。以下是简化版的 register_taxonomy()
流程(基于 WordPress 6.x 的源码):
-
参数校验与标准化:
函数首先会对传入的参数进行各种校验,确保分类法名称合法、对象类型存在等等。同时,会对
$args
数组进行标准化,设置一些默认值。function register_taxonomy( $taxonomy, $object_type, $args = array() ) { global $wp_taxonomies, $wp_object_types; // 注意!这里声明了全局变量 // 1. 参数校验 if ( ! is_string( $taxonomy ) || '' === $taxonomy ) { _doing_it_wrong( __FUNCTION__, __( 'Taxonomy names must be strings.' ), '3.0' ); return new WP_Error( 'invalid_taxonomy', __( 'Taxonomy names must be strings.' ) ); } // ... (其他校验代码) ... // 2. 参数标准化 $args = wp_parse_args( $args ); // 合并用户传入的 $args 和默认值 // ... (更多参数处理) ...
-
创建
WP_Taxonomy
对象:接下来,函数会创建一个
WP_Taxonomy
类的实例,并将分类法的各种信息(名称、对象类型、配置选项)存储在这个对象中。// 3. 创建 WP_Taxonomy 对象 $wp_taxonomies[ $taxonomy ] = new WP_Taxonomy( $taxonomy, $object_type, $args ); // ...
-
更新
$wp_taxonomies
全局变量:最关键的一步来了! 函数将刚刚创建的
WP_Taxonomy
对象,以分类法名称为键,存储到$wp_taxonomies
全局变量中。 注意,global $wp_taxonomies;
声明了register_taxonomy()
函数可以访问和修改全局变量$wp_taxonomies
。// 4. 更新 $wp_taxonomies 全局变量 $wp_taxonomies[ $taxonomy ] = new WP_Taxonomy( $taxonomy, $object_type, $args );
这就相当于把分类法的信息放到了公共储物柜里,供 WordPress 的其他部分使用。
-
更新
$wp_object_types
全局变量:register_taxonomy()
还会更新$wp_object_types
变量,建立分类法和对象类型之间的关联。 这部分代码稍微复杂一些,因为它要处理一个分类法与多个对象类型关联的情况。// 5. 更新 $wp_object_types 全局变量 foreach ( (array) $object_type as $type ) { if ( ! isset( $wp_object_types[ $type ] ) ) { $wp_object_types[ $type ] = array(); } $wp_object_types[ $type ][] = $taxonomy; }
这段代码遍历所有与该分类法关联的对象类型,然后将分类法名称添加到对应对象类型的数组中。 这样,WordPress 就能知道哪些分类法与哪些对象类型相关联。
第四幕:WP_Taxonomy
类,分类法的容器
WP_Taxonomy
类是 WordPress 用来表示分类法的核心类。 它包含了分类法的各种属性和方法。 咱们来看看它的主要属性:
属性名称 | 描述 |
---|---|
name |
分类法的名称,比如 ‘category’。 |
object_type |
与分类法关联的对象类型,比如 ‘post’。 |
label |
分类法的标签,用于在后台界面显示。 |
labels |
一个包含各种标签的数组,比如 ‘name’ (分类法名称)、’singular_name’ (单数名称)、’edit_item’ (编辑项目) 等等。 |
description |
分类法的描述。 |
public |
是否公开,决定了分类法是否可以在前端访问。 |
hierarchical |
是否是分层结构,决定了分类法是否可以像分类一样有父子关系。 |
rewrite |
一个包含重写规则的数组,决定了分类法的 URL 结构。 |
query_var |
用于查询分类法数据的查询变量名称。 |
show_admin_column |
是否在文章列表页面显示分类法的管理列。 |
WP_Taxonomy
类还包含一些方法,用于获取和设置分类法的属性,以及执行一些与分类法相关的操作。
第五幕:代码示例,一睹真容
为了更好地理解 register_taxonomy()
的工作原理,咱们来看一个具体的代码示例:
function my_custom_taxonomy() {
$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' => 'movie_genre' ),
);
register_taxonomy( 'movie_genre', 'post', $args );
}
add_action( 'init', 'my_custom_taxonomy', 0 );
这段代码定义了一个名为 movie_genre
的自定义分类法,用于对电影文章进行分类。它指定了分类法的各种标签和配置选项,并将其与 post
对象类型关联。
当 WordPress 执行这段代码时,register_taxonomy()
函数会将 movie_genre
分类法的相关信息存储到 $wp_taxonomies
和 $wp_object_types
全局变量中。 这样,WordPress 就能知道存在一个名为 movie_genre
的分类法,并且它与 post
对象类型相关联。
第六幕:幕后花絮,深入挖掘
- 插件中的分类法: 插件通常会在插件文件中使用
register_taxonomy()
注册自定义分类法。为了确保分类法在 WordPress 初始化完成后注册,插件通常会将register_taxonomy()
函数挂载到init
动作钩子上,并设置一个较低的优先级(比如 0 或 1)。 - 主题中的分类法: 主题也可以注册自定义分类法,但通常不建议这样做。因为当主题被切换时,分类法也会随之消失,导致数据丢失。 最好将自定义分类法放在插件中,以确保数据的持久性。
- 性能考量: 注册过多的分类法可能会影响 WordPress 的性能,因为每次加载页面时,WordPress 都要加载所有已注册的分类法信息。 因此,应该尽量减少不必要的分类法注册。
unregister_taxonomy()
函数: 与register_taxonomy()
相对应的是unregister_taxonomy()
函数,用于注销已注册的分类法。 但需要注意的是,注销分类法并不会删除已存在的分类法数据,只是将其从 WordPress 的管理界面中移除。
第七幕:总结与展望
今天,咱们一起深入剖析了 register_taxonomy()
函数的源码,了解了它是如何将分类法信息添加到全局变量 Array
中的。 register_taxonomy()
函数是 WordPress 中一个非常重要的函数,它为我们提供了强大的分类和组织内容的能力。
希望通过今天的讲解,大家对 WordPress 的分类法机制有了更深入的理解。 掌握了这些知识,你就可以更好地利用 WordPress 的分类法功能,构建更灵活、更强大的网站。
下次有机会,我们再一起探讨 WordPress 的其他核心机制! 谢谢大家!