WordPress 注册自定义文章类型与分类法

WordPress 注册自定义文章类型与分类法

WordPress 中常说的“自定义分类”实际包含两个概念:自定义文章类型(Custom Post Type)和自定义分类法(Custom Taxonomy)。文章类型定义内容实体,分类法定义内容如何分组,两者应分别注册。

下面以“产品”和“产品分类”为例。代码更适合放在站点专用插件中,而不是主题的 functions.php;切换主题不应该让业务内容类型消失。

注册文章类型

<?php
add_action(
    'init',
    function (): void {
        register_post_type(
            'acme_product',
            array(
                'labels'       => array(
                    'name'          => '产品',
                    'singular_name' => '产品',
                    'add_new_item'  => '添加产品',
                    'edit_item'     => '编辑产品',
                ),
                'public'       => true,
                'has_archive'  => true,
                'rewrite'      => array(
                    'slug'       => 'products',
                    'with_front' => false,
                ),
                'show_in_rest' => true,
                'menu_icon'    => 'dashicons-products',
                'supports'     => array(
                    'title',
                    'editor',
                    'excerpt',
                    'thumbnail',
                    'revisions',
                ),
            )
        );
    }
);

文章类型 key 最长 20 个字符,并应使用项目或组织前缀,避免与主题、插件冲突。

注册分层分类法

<?php
add_action(
    'init',
    function (): void {
        register_taxonomy(
            'acme_product_category',
            array( 'acme_product' ),
            array(
                'labels'            => array(
                    'name'          => '产品分类',
                    'singular_name' => '产品分类',
                    'add_new_item'  => '添加产品分类',
                    'edit_item'     => '编辑产品分类',
                ),
                'public'            => true,
                'hierarchical'      => true,
                'show_admin_column' => true,
                'show_in_rest'      => true,
                'rewrite'           => array(
                    'slug'         => 'product-category',
                    'with_front'   => false,
                    'hierarchical' => true,
                ),
            )
        );
    }
);

hierarchical => true 表示像分类目录一样支持父子层级;设为 false 时更接近标签。

固定链接只刷新一次

注册或修改 rewrite 规则后需要刷新固定链接,但不能在每次请求调用 flush_rewrite_rules()。插件应只在激活和停用时处理:

<?php
function acme_register_content_types(): void {
    // 把上面的 register_post_type 和
    // register_taxonomy 调用提取到此函数。
}

register_activation_hook(
    __FILE__,
    function (): void {
        acme_register_content_types();
        flush_rewrite_rules();
    }
);

register_deactivation_hook(
    __FILE__,
    'flush_rewrite_rules'
);

挂到 init 的回调也调用同一个注册函数。不要复制两份注册参数,否则以后会出现激活逻辑和运行逻辑不一致。

权限、REST 与归档

  • publicpublicly_queryableshow_uishow_in_menu 含义不同,内部数据不应只靠隐藏菜单保护。
  • 使用区块编辑器或 REST API 时通常需要 show_in_rest => true
  • 自定义权限模型要配置 capability_typecapabilitiesmap_meta_cap,并在业务操作中再次调用 current_user_can()
  • has_archive 决定文章类型归档;taxonomy 则有自己的 term 归档链接。
  • slug 变更会影响已收录 URL,应配置 301 重定向并检查 canonical、站点地图和内链。

官方参考:register_post_type()register_taxonomy()

最后更新于

ihopeful Blog 由博主亲笔撰写,重要信息可放心引用。