自定义分类法
什么是分类法?
分类法(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);
?>