WordPress函数get_post_type_object如何构建自定义内容类型的属性对象

好的,我们现在开始深入探讨 WordPress 函数 get_post_type_object(),以及它如何构建自定义内容类型的属性对象。

核心概念:理解 Post Type Object

在深入了解 get_post_type_object() 之前,首先需要理解什么是 Post Type Object。在 WordPress 中,每种内容类型(例如文章、页面、自定义内容类型)都有一个与之关联的 Post Type Object。这个对象包含了关于该内容类型的所有信息,包括它的标签、支持的功能、管理界面设置等等。

Post Type Object 是 WP_Post_Type 类的一个实例。这个类定义了内容类型的所有属性和方法。

get_post_type_object() 函数的作用

get_post_type_object() 函数的主要作用是检索指定内容类型的 Post Type Object。如果该内容类型的 Post Type Object 已经存在(例如,通过 register_post_type() 函数注册),那么 get_post_type_object() 将返回该对象。如果该内容类型不存在,则返回 null

函数签名:

/**
 * Retrieves a post type object by name.
 *
 * @since 3.0.0
 *
 * @param string $post_type Post type name.
 * @return WP_Post_Type|null WP_Post_Type object if it exists, null otherwise.
 */
function get_post_type_object( $post_type ) {
    global $wp_post_types;

    if ( isset( $wp_post_types[ $post_type ] ) ) {
        return $wp_post_types[ $post_type ];
    }

    return null;
}

代码分析:

  1. 全局变量 $wp_post_types get_post_type_object() 函数首先访问全局变量 $wp_post_types。这是一个关联数组,用于存储所有已注册的内容类型的 Post Type Object。数组的键是内容类型的名称(例如 ‘post’, ‘page’, ‘my_custom_post_type’),值是对应的 WP_Post_Type 对象。

  2. 检查是否存在: 函数使用 isset( $wp_post_types[ $post_type ] ) 来检查指定的内容类型 $post_type 是否已经注册,也就是在 $wp_post_types 数组中是否存在。

  3. 返回对象或 null: 如果内容类型存在,函数直接从 $wp_post_types 数组中返回对应的 WP_Post_Type 对象。如果内容类型不存在,函数返回 null

构建自定义内容类型的属性对象的过程

构建自定义内容类型的属性对象的核心在于 register_post_type() 函数。这个函数负责注册一个新的内容类型,并创建相应的 WP_Post_Type 对象,然后将这个对象存储到 $wp_post_types 全局数组中。

以下是一个详细的例子,演示如何使用 register_post_type() 函数来注册一个自定义内容类型,并分析如何构建其属性对象:

<?php
/**
 * 注册自定义内容类型 "书籍"
 */
function register_book_post_type() {

    $labels = array(
        'name'               => _x( '书籍', 'post type general name', 'my-plugin' ),
        'singular_name'      => _x( '书籍', 'post type singular name', 'my-plugin' ),
        'menu_name'          => _x( '书籍', 'admin menu', 'my-plugin' ),
        'name_admin_bar'     => _x( '书籍', 'add new on admin bar', 'my-plugin' ),
        'add_new'            => _x( '添加新书籍', 'book', 'my-plugin' ),
        'add_new_item'       => __( '添加新书籍', 'my-plugin' ),
        'new_item'           => __( '新书籍', 'my-plugin' ),
        'edit_item'          => __( '编辑书籍', 'my-plugin' ),
        'view_item'          => __( '查看书籍', 'my-plugin' ),
        'all_items'          => __( '所有书籍', 'my-plugin' ),
        'search_items'       => __( '搜索书籍', 'my-plugin' ),
        'parent_item_colon'  => __( '父级书籍:', 'my-plugin' ),
        'not_found'          => __( '未找到书籍.', 'my-plugin' ),
        'not_found_in_trash' => __( '回收站中未找到书籍.', 'my-plugin' )
    );

    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'book' ),
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
        'taxonomies'          => array( 'category', 'post_tag' ), // 默认分类和标签
        'show_in_rest'       => true  // 启用 Gutenberg 编辑器
    );

    register_post_type( 'book', $args );
}
add_action( 'init', 'register_book_post_type' );

//使用示例
function display_book_details() {
    $book_type = get_post_type_object('book');

    if ($book_type) {
        echo '内容类型名称: ' . $book_type->label . '<br>'; // 输出 "书籍"
        echo '是否公开: ' . ($book_type->public ? '是' : '否') . '<br>'; // 输出 "是"

        // 输出所有支持的功能
        echo '支持的功能: <br>';
        if (is_array($book_type->supports)) {
            foreach ($book_type->supports as $feature) {
                echo '- ' . $feature . '<br>';
            }
        }

    } else {
        echo '内容类型 "book" 未找到.';
    }
}

add_action('wp_footer', 'display_book_details');

代码解释:

  1. register_book_post_type() 函数: 这个函数定义了如何注册名为 ‘book’ 的自定义内容类型。

  2. $labels 数组: $labels 数组包含了用于内容类型界面的各种文本标签,例如名称、单数名称、添加新项目等等。这些标签将被用于管理界面,例如文章列表、编辑页面等等。

  3. $args 数组: $args 数组包含了内容类型的各种属性和设置。以下是一些重要的属性:

    • public:指定内容类型是否公开可见。如果为 true,则可以在网站前台访问。
    • publicly_queryable:指定内容类型是否可以通过查询来访问。
    • show_ui:指定是否在 WordPress 管理界面中显示内容类型的用户界面。
    • show_in_menu:指定是否在管理菜单中显示内容类型。
    • rewrite:指定内容类型的 URL 重写规则。
    • capability_type:指定内容类型的权限类型。
    • has_archive:指定内容类型是否有存档页面。
    • hierarchical:指定内容类型是否具有层级结构(例如页面)。
    • supports:指定内容类型支持的功能,例如标题、编辑器、作者、特色图像等等。
    • taxonomies: 指定内容类型关联的分类法(如category、post_tag)。
    • show_in_rest: 是否在 Gutenberg 编辑器中显示,启用后才能使用区块编辑器。
  4. register_post_type( 'book', $args ) 这个函数调用实际注册了内容类型。它会创建一个 WP_Post_Type 对象,并将 $args 数组中的属性值赋给该对象。然后,它将该对象存储到 $wp_post_types 全局数组中,键名为 ‘book’。

  5. get_post_type_object('book')display_book_details() 函数中,我们调用 get_post_type_object('book') 来检索 ‘book’ 内容类型的 Post Type Object。

  6. 访问属性: 一旦我们获得了 Post Type Object,我们就可以访问它的属性,例如 $book_type->label(内容类型名称)和 $book_type->public(是否公开)。

WP_Post_Type 类的属性

WP_Post_Type 类定义了许多属性,这些属性描述了内容类型的各个方面。以下是一些常用的属性:

属性名 类型 描述
name string 内容类型的名称(例如 ‘post’, ‘page’, ‘book’)。
label string 内容类型的标签,用于管理界面。
labels array 包含各种文本标签的数组,用于内容类型的界面。
description string 内容类型的描述。
public bool 指定内容类型是否公开可见。
publicly_queryable bool 指定内容类型是否可以通过查询来访问。
show_ui bool 指定是否在 WordPress 管理界面中显示内容类型的用户界面。
show_in_menu bool 指定是否在管理菜单中显示内容类型。
show_in_rest bool 指定是否在 Gutenberg 编辑器中显示内容类型。
rest_base string REST API 的基础路由。
rest_controller_class string 用于 REST API 的控制器类。
query_var mixed 指定内容类型是否可以使用查询变量来访问。
rewrite mixed 指定内容类型的 URL 重写规则。
capability_type string 指定内容类型的权限类型。
capabilities array 指定内容类型的权限。
map_meta_cap bool 指定是否将默认的 meta capabilities 映射到内容类型的 capabilities。
has_archive mixed 指定内容类型是否有存档页面。
hierarchical bool 指定内容类型是否具有层级结构(例如页面)。
menu_position int 指定内容类型在管理菜单中的位置。
menu_icon string 指定内容类型在管理菜单中显示的图标。
supports array 指定内容类型支持的功能,例如标题、编辑器、作者、特色图像等等。
taxonomies array 指定内容类型关联的分类法。

使用 get_post_type_object() 的实际场景

get_post_type_object() 函数在许多实际场景中都非常有用:

  • 动态生成管理界面: 你可以使用 get_post_type_object() 来动态生成自定义内容类型的管理界面,例如文章列表、编辑页面等等。
  • 控制访问权限: 你可以使用 get_post_type_object() 来检查用户是否有权访问某个内容类型。
  • 自定义 URL 重写规则: 你可以使用 get_post_type_object() 来自定义内容类型的 URL 重写规则。
  • 扩展内容类型的功能: 你可以使用 get_post_type_object() 来扩展内容类型的功能,例如添加自定义字段、修改编辑界面等等。
  • 条件判断: 在主题或插件中,根据不同的内容类型显示不同的内容或应用不同的逻辑。

高级用法:修改已注册内容类型的属性

虽然通常情况下,我们会在 register_post_type() 函数中定义内容类型的所有属性,但有时我们可能需要在之后修改某些属性。这可以通过以下方式实现:

<?php
/**
 * 修改已注册内容类型 "书籍" 的属性
 */
function modify_book_post_type() {
    global $wp_post_types;

    if ( isset( $wp_post_types['book'] ) ) {
        // 获取 'book' 内容类型的 Post Type Object
        $book_type = $wp_post_types['book'];

        // 修改标签
        $book_type->labels->name = __( '图书', 'my-plugin' );
        $book_type->labels->singular_name = __( '图书', 'my-plugin' );

        // 修改支持的功能
        $book_type->supports = array( 'title', 'editor', 'thumbnail' );

        // 你还可以修改其他属性,例如:
        // $book_type->public = false;
    }
}
add_action( 'init', 'modify_book_post_type', 11 ); // 优先级要高于 register_post_type

注意事项:

  • 优先级: 修改内容类型属性的代码必须在 register_post_type() 函数执行之后执行。因此,你需要使用 add_action() 函数来挂载你的修改函数,并确保它的优先级高于 register_post_type() 函数的优先级(通常是 10)。
  • 谨慎修改: 修改已注册的内容类型的属性可能会影响网站的正常运行。因此,你应该谨慎修改,并确保你的修改不会导致任何问题。
  • WP_Post_Type 对象的直接访问: 直接访问 $wp_post_types 全局数组中的 WP_Post_Type 对象并修改其属性是一种直接的方法。虽然有效,但应当谨慎使用。 更好的方法是使用 WordPress 提供的钩子和过滤器来修改内容类型的行为。 例如,可以使用 register_post_type_args 过滤器来修改传递给 register_post_type 函数的参数。

使用 register_post_type_args 过滤器

<?php
/**
 * 使用 register_post_type_args 过滤器修改内容类型参数
 */
function modify_book_post_type_args( $args, $post_type ) {
    if ( 'book' === $post_type ) {
        $args['labels']['name'] = __( '图书', 'my-plugin' );
        $args['labels']['singular_name'] = __( '图书', 'my-plugin' );
        $args['supports'] = array( 'title', 'editor', 'thumbnail' );
    }

    return $args;
}
add_filter( 'register_post_type_args', 'modify_book_post_type_args', 10, 2 );

这个例子展示了如何使用 register_post_type_args 过滤器来修改传递给 register_post_type 函数的参数。这种方法更加安全和灵活,因为它允许你在注册内容类型之前修改参数。

总结:理解内容类型注册和对象构建

get_post_type_object() 函数是 WordPress 中一个重要的工具,它允许你检索指定内容类型的属性对象。理解 register_post_type() 函数如何创建和注册内容类型,以及 WP_Post_Type 类的属性,对于有效地使用 get_post_type_object() 至关重要。 通过掌握这些概念,你可以更好地自定义和管理你的 WordPress 网站的内容类型。

发表回复

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