Skip to content

自定义分类法

什么是分类法?

分类法(Taxonomy)是用于对内容进行分组的机制。WordPress 内置两种分类法:

分类法特点层级
分类目录 (Categories)有层级,适合大类支持
标签 (Tags)无层级,适合关键词不支持

自定义分类法允许你创建类似分类和标签的结构,但完全自定义。

自定义分类法的应用

常见场景

  • 产品分类 - 产品类型、品牌、颜色
  • 地理位置 - 国家、省份、城市
  • 时间周期 - 季节、年代
  • 技能标签 - 编程语言、框架
  • 难度级别 - 初级、中级、高级
  • 课程章节 - 教程的章节分类

示例

教程 (自定义分类法: tutorial_category)
├── 入门
│   ├── 安装配置
│   └── 基本操作
├── 进阶
│   ├── 主题开发
│   └── 插件开发
└── 高级
    ├── REST API
    └── 性能优化

注册自定义分类法

基本代码

php
<?php
// functions.php 或插件文件

function my_custom_taxonomies() {
    // 注册分类法
    register_taxonomy('portfolio_category', 'portfolio', array(
        'labels' => array(
            'name'              => '作品分类',
            'singular_name'     => '作品分类',
            'search_items'      => '搜索作品分类',
            'all_items'         => '所有作品分类',
            'edit_item'         => '编辑作品分类',
            'update_item'       => '更新作品分类',
            'add_new_item'      => '添加新作品分类',
            'new_item_name'     => '新作品分类名称',
            'menu_name'         => '作品分类',
        ),
        'hierarchical'      => true,       // true=分类样式, false=标签样式
        'show_ui'           => true,       // 显示在后台 UI
        'show_admin_column' => true,       // 在列表页显示列
        'query_var'         => true,      // 允许查询变量
        'rewrite'           => array(
            'slug' => 'portfolio-category'
        ),
        'show_in_rest'      => true,      // REST API 支持
    ));
}
add_action('init', 'my_custom_taxonomies');

层级分类 vs 标签

层级分类(hierarchical: true)

php
register_taxonomy('product_category', 'product', array(
    'hierarchical' => true,
    // 像分类目录一样工作,有父子关系
));
// 输出类似:分类目录

非层级(标签样式)(hierarchical: false)

php
register_taxonomy('product_tag', 'product', array(
    'hierarchical' => false,
    // 像标签一样工作,无层级
));
// 输出类似:标签云

完整参数

php
<?php
register_taxonomy('taxonomy_name', 'post_type', array(
    // === 标签 ===
    'labels' => array(
        'name'                  => '名称',
        'singular_name'         => '单数名称',
        'search_items'          => '搜索',
        'popular_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'             => '无项目',
        'items_list_navigation' => '项目列表导航',
        'items_list'           => '项目列表',
        'most_used'             => '最常用',
        'back_to_items'         => '返回项目',
    ),
    
    // === 公开性 ===
    'public'            => true,
    'show_ui'           => true,
    'show_in_nav_menus' => true,
    'show_in_menu'      => true,
    'show_tagcloud'     => true,        // 在标签云小工具中显示
    'show_in_quick_edit'=> true,
    'show_admin_column' => true,        // 在文章列表显示列
    
    // === 层级 ===
    'hierarchical'      => true,
    
    // === 查询 ===
    'query_var'         => true,
    'query_var_string'  => 'custom_var',  // 自定义查询变量名
    
    // === 永久链接 ===
    'rewrite' => array(
        'slug'          => 'taxonomy-slug',
        'with_front'    => true,
        'hierarchical'  => true,        // 层级 URL
        'ep_mask'       => EP_NONE,
    ),
    
    // === REST API ===
    'show_in_rest'      => true,
    'rest_base'         => 'taxonomy-slug',
    'rest_controller_class' => 'WP_REST_Terms_Controller',
    
    // === 其他 ===
    'sort'              => false,
    'args'              => array(
        'orderby' => 'term_order',
    ),
    '_builtin'          => false,
));

创建配套模板

taxonomy-{taxonomy}.php

php
<?php
/**
 * 作品分类存档模板
 */
get_header(); ?>

<main class="taxonomy-archive">
    <header class="archive-header">
        <?php 
        $term = get_queried_object();
        ?>
        <span class="term-type">作品分类</span>
        <h1><?php echo $term->name; ?></h1>
        
        <?php if ($term->description): ?>
            <p class="term-description"><?php echo $term->description; ?></p>
        <?php endif; ?>
        
        <div class="term-meta">
            <span><?php echo $term->count; ?> 个作品</span>
        </div>
    </header>
    
    <!-- 子分类 -->
    <?php
    $child_terms = get_terms(array(
        'taxonomy'   => $term->taxonomy,
        'parent'     => $term->term_id,
        'hide_empty' => false,
    ));
    
    if ($child_terms && !is_wp_error($child_terms)): ?>
        <nav class="child-terms">
            <h3>子分类</h3>
            <ul>
                <?php foreach ($child_terms as $child): ?>
                    <li>
                        <a href="<?php echo get_term_link($child); ?>">
                            <?php echo $child->name; ?>
                            <span>(<?php echo $child->count; ?>)</span>
                        </a>
                    </li>
                <?php endforeach; ?>
            </ul>
        </nav>
    <?php endif; ?>
    
    <!-- 文章列表 -->
    <div class="posts-grid">
        <?php
        while (have_posts()): the_post();
            // 输出文章卡片
        ?>
            <article class="post-card">
                <!-- ... -->
            </article>
        <?php endwhile; ?>
    </div>
    
    <?php the_posts_pagination(); ?>
</main>

<?php get_footer(); ?>

标签云样式 (非层级)

php
<?php
// 非层级分类法可以使用标签云
wp_tag_cloud(array(
    'taxonomy'  => 'portfolio_tag',
    'smallest'  => 12,
    'largest'   => 28,
    'unit'      => 'px',
    'number'    => 20,
    'format'    => 'flat',    // flat, list, array
    'separator' => ' ',
    'orderby'   => 'count',  // name, count
    'order'     => 'DESC',
));

分类法与文章类型关联

关联多个文章类型

php
<?php
// 一个分类法关联多个文章类型
register_taxonomy('project_tag', array('portfolio', 'case_study'), array(
    'hierarchical' => false,
    'labels' => array(
        'name' => '项目标签',
    ),
));

获取分类法中的术语

php
<?php
// 获取某个分类法的所有术语
$terms = get_terms(array(
    'taxonomy'   => 'portfolio_category',
    'hide_empty' => true,         // 隐藏空术语
    'orderby'    => 'name',
    'order'      => 'ASC',
    'parent'     => 0,            // 只获取顶级
));

// 获取当前文章的术语
$post_terms = get_the_terms(get_the_ID(), 'portfolio_category');

// 获取分类法中的热门术语
$popular_terms = get_terms(array(
    'taxonomy'   => 'portfolio_category',
    'number'     => 10,
    'orderby'    => 'count',
    'order'      => 'DESC',
));

在模板中使用

输出术语

php
<?php
// 获取并输出术语
$terms = get_the_terms(get_the_ID(), 'portfolio_category');

if ($terms && !is_wp_error($terms)) {
    echo '<div class="terms-list">';
    foreach ($terms as $term) {
        echo '<a href="' . get_term_link($term) . '">';
        echo $term->name;
        echo '</a>';
    }
    echo '</div>';
}
?>

输出术语(带样式)

php
<?php
// 带逗号分隔的术语列表
$terms = get_the_terms(get_post()->ID, 'portfolio_category');
if ($terms) {
    $term_names = wp_list_pluck($terms, 'name');
    echo implode(', ', $term_names);
}
?>

<!-- 带链接的术语 -->
<?php
echo get_the_term_list(
    get_the_ID(), 
    'portfolio_category', 
    '<span class="portfolio-cats">', 
    ', ', 
    '</span>'
);
?>

按分类法查询文章

php
<?php
// 查询特定分类法下的文章
$args = array(
    'post_type'      => 'portfolio',
    'posts_per_page' => 10,
    'tax_query'      => array(
        array(
            'taxonomy' => 'portfolio_category',
            'field'    => 'slug',
            'terms'    => 'web-design',
        ),
    ),
);

// 多个分类(AND 关系)
$args['tax_query'] = array(
    'relation' => 'AND',
    array(
        'taxonomy' => 'portfolio_category',
        'field'    => 'slug',
        'terms'    => array('web-design', 'branding'),
    ),
    array(
        'taxonomy' => 'portfolio_tag',
        'field'    => 'slug',
        'terms'    => 'featured',
    ),
);

// 多个分类(OR 关系)
$args['tax_query'] = array(
    'relation' => 'OR',
    array(
        'taxonomy' => 'portfolio_category',
        'field'    => 'slug',
        'terms'    => array('web-design', 'branding'),
    ),
);

$query = new WP_Query($args);
?>

分类法管理界面

在后台显示

WordPress 会自动在指定文章类型的后台添加分类法管理界面。

添加自定义列

php
<?php
// 添加分类术语到文章列表列
function add_taxonomy_columns($columns) {
    $columns['portfolio_category'] = '分类';
    return $columns;
}
add_filter('manage_posts_columns', 'add_taxonomy_columns');

function render_taxonomy_columns($column, $post_id) {
    if ($column === 'portfolio_category') {
        $terms = get_the_terms($post_id, 'portfolio_category');
        if ($terms) {
            $output = array();
            foreach ($terms as $term) {
                $output[] = sprintf(
                    '<a href="%s">%s</a>',
                    get_edit_term_link($term->term_id, 'portfolio_category'),
                    esc_html($term->name)
                );
            }
            echo implode(', ', $output);
        } else {
            echo '—';
        }
    }
}
add_action('manage_posts_custom_column', 'render_taxonomy_columns', 10, 2);

分类法权限

php
<?php
// 自定义分类法权限
register_taxonomy('private_docs', 'document', array(
    'capabilities' => array(
        'manage_terms' => 'manage_options',
        'edit_terms'   => 'manage_options',
        'delete_terms' => 'manage_options',
        'assign_terms' => 'edit_posts',
    ),
));

完整示例:产品分类

php
<?php
// 注册产品分类法
function register_product_taxonomies() {
    // 产品品牌(非层级)
    register_taxonomy('brand', 'product', array(
        'hierarchical' => false,
        'show_admin_column' => true,
        'rewrite' => array('slug' => 'brand'),
        'show_in_rest' => true,
    ));
    
    // 产品分类(层级)
    register_taxonomy('product_cat', 'product', array(
        'hierarchical' => true,
        'show_admin_column' => true,
        'rewrite' => array('slug' => 'product-category'),
        'show_in_rest' => true,
        'show_in_quick_edit' => true,
    ));
    
    // 产品标签(非层级)
    register_taxonomy('product_tag', 'product', array(
        'hierarchical' => false,
        'show_admin_column' => true,
        'rewrite' => array('slug' => 'product-tag'),
        'show_in_rest' => true,
    ));
}
add_action('init', 'register_product_taxonomies');

高级技巧

获取术语的子术语

php
<?php
function get_child_terms($parent_id, $taxonomy) {
    return get_terms(array(
        'taxonomy'   => $taxonomy,
        'parent'     => $parent_id,
        'hide_empty' => false,
    ));
}

// 使用
$main_cats = get_terms('portfolio_category', array('parent' => 0));
foreach ($main_cats as $cat) {
    echo $cat->name;
    $children = get_child_terms($cat->term_id, 'portfolio_category');
    // 输出子分类...
}
?>

术语颜色/图像

术语可以存储元数据:

```php
<?php
// 保存术语颜色
function save_term_color($term_id) {
    if (isset($_POST['term_color'])) {
        update_term_meta($term_id, 'term_color', sanitize_hex_color($_POST['term_color']));
    }
}
add_action('edited_term', 'save_term_color');

// 获取术语颜色
$color = get_term_meta($term_id, 'term_color', true);
?>

基于 WordPress官方文档 构建