taxonomy分类法
分类法
分类法是一个奇特的词,用于对事物进行分类/分组。分类法可以是分层的(父级/子级)或扁平的。
WordPress 将分类法存储在term_taxonomy
数据库表中,允许开发人员沿着已有的分类法注册自定义分类法。
分类法有一些术语,可作为您对事物进行分类/分组的主题。它们存储在terms
表内。
例如:名为“艺术”的分类法可以有多个术语,例如“现代”和“18 世纪”。
本章将向您展示如何注册自定义分类法、如何从数据库检索其内容以及如何将其呈现给公众。
使用自定义分类法
分类法简介
要了解分类法是什么及其用途,请阅读分类法简介。
自定义分类法
随着分类系统的发展,“类别”和“标签”并不是非常结构化,因此开发人员创建自己的类别可能会有好处。
WordPress 允许开发人员创建自定义分类法。当人们想要创建不同的命名系统并使其以可预测的方式在幕后访问时,自定义分类法非常有用。
为什么使用自定义分类法?
您可能会问,“当我可以按类别和标签进行组织时,为什么还要创建自定义分类法呢?”
好吧……让我们举个例子。假设我们有一位厨师客户,希望您创建一个网站,在其中展示她的原创食谱。
组织网站的一种方法可能是创建一个名为“食谱”的自定义帖子类型来存储她的食谱。然后创建一个分类法“课程”以将“开胃菜”与“甜点”分开,最后创建一个分类法“成分”以将“鸡肉”与“巧克力”菜肴分开。
这些组可以使用类别或标签来定义,您可以有一个“课程”类别,其中包含“开胃菜”和“甜点”的子类别,以及一个“成分”类别,其中每种成分都有子类别。
使用自定义分类法的主要优点是您可以独立于类别和标签引用“课程”和“成分”。他们甚至在管理区域拥有自己的菜单。
此外,创建自定义分类法允许您构建自定义界面,这将简化客户的生活,并使插入数据的过程直观地了解其业务性质。
现在想象一下这些自定义分类法和接口是在插件内实现的;您刚刚构建了自己的食谱插件,可以在任何 WordPress 网站上重复使用。
示例:课程分类
以下示例将向您展示如何创建一个插件,将自定义分类“课程”添加到默认post
帖子类型。请注意,添加自定义分类法的代码不必位于其自己的插件中;如果需要,它可以包含在主题中或作为现有插件的一部分。
在尝试创建您自己的插件之前,请务必阅读插件基础知识章节。
第 1 步:开始之前
转到帖子 > 添加新页面。您会注意到您只有类别和标签。
第 2 步:创建一个新插件
使用操作挂钩为帖子类型“帖子”注册分类“课程” init
。
/*
* Plugin Name: Course Taxonomy
* Description: A short example showing how to add a taxonomy called Course.
* Version: 1.0
* Author: developer.wordpress.org
* Author URI: https://codex.wordpress.org/User:Aternus
*/
function wporg_register_taxonomy_course() {
$labels = array(
'name' => _x( 'Courses', 'taxonomy general name' ),
'singular_name' => _x( 'Course', 'taxonomy singular name' ),
'search_items' => __( 'Search Courses' ),
'all_items' => __( 'All Courses' ),
'parent_item' => __( 'Parent Course' ),
'parent_item_colon' => __( 'Parent Course:' ),
'edit_item' => __( 'Edit Course' ),
'update_item' => __( 'Update Course' ),
'add_new_item' => __( 'Add New Course' ),
'new_item_name' => __( 'New Course Name' ),
'menu_name' => __( 'Course' ),
);
$args = array(
'hierarchical' => true, // make it hierarchical (like categories)
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => [ 'slug' => 'course' ],
);
register_taxonomy( 'course', [ 'post' ], $args );
}
add_action( 'init', 'wporg_register_taxonomy_course' );
第 3 步:查看结果
激活您的插件,然后转到帖子 > 添加新插件。您应该会看到“课程”分类的新元框。
代码分解
以下讨论分解了上面使用的代码,描述了函数和参数。
该函数wporg_register_taxonomy_course
包含注册自定义分类法所需的所有步骤。
该$labels
数组包含自定义分类法的标签。
这些标签将用于在管理区域中显示有关分类的各种信息。
该$args
数组包含创建自定义分类法时将使用的配置选项。
函数register_taxonomy()使用配置数组 创建一个带有帖子类型标识符的新分类法course
。post
$args
函数add_action()wporg_register_taxonomy_course
将函数执行与操作挂钩 联系起来init
。
$参数
$args 数组保存自定义分类法的重要配置,它指示 WordPress 分类法应如何工作。
查看register_taxonomy() 函数以获取可接受参数的完整列表以及每个参数的作用。
概括
通过我们的课程分类示例,WordPress 将自动为分类创建存档页面和子页面course
。
存档页面将/course/
使用 Term 的 slug ( /course/%%term-slug%%/
) 在其下方生成子页面。
使用你的分类法
WordPress 具有许多与您的自定义分类法及其中的术语进行交互的功能。
这里有些例子:
the_terms
:采用分类法参数并在列表中呈现术语。wp_tag_cloud
:采用分类法参数并呈现术语的标签云。is_taxonomy
:允许您确定给定的分类是否存在。
术语分割 (WordPress 4.2)
此信息出于历史目的而放在这里。如果您对 2015 年之前的术语如何运作不感兴趣,您可以跳过本节。
WordPress 4.2 之前的版本
具有相同 slug 的不同分类法中的术语共享一个术语 ID。例如,带有“新闻”标签的标签和类别具有相同的术语 ID。
WordPress 4.2+
从 4.2 开始,当这些共享术语之一更新时,它将被拆分:更新的术语将被分配一个新的术语 ID。
这对你来说意味着什么?
在绝大多数情况下,此更新是无缝且顺利的。但是,一些将术语 ID 存储在选项、帖子元、用户元或其他位置的插件和主题可能会受到影响。
处理分裂
WordPress 4.2 包含两种不同的工具来帮助插件和主题的作者进行过渡。
钩子split_shared_term
_
当为共享术语分配新术语 ID 时,split_shared_term
会触发新操作。
以下是插件和主题作者如何利用此挂钩来确保更新存储的术语 ID 的一些示例。
存储在选项中的术语 ID
假设您的插件存储一个名为的选项featured_tags
,其中包含一组术语 ID ( [4, 6, 10]
),用作主页精选帖子部分的查询参数。
在此示例中,您将挂钩split_shared_term
操作,检查更新的术语 ID 是否在数组中,并在必要时进行更新。
/**
* Update featured_tags option when a shared term gets split.
*
* @param int $term_id ID of the formerly shared term.
* @param int $new_term_id ID of the new term created for the $term_taxonomy_id.
* @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split.
* @param string $taxonomy Taxonomy for the split term.
*/
function wporg_featured_tags_split( int $term_id, int $new_term_id, int $term_taxonomy_id, string $taxonomy ): void {
// we only care about tags, so we'll first verify that the taxonomy is post_tag.
if ( 'post_tag' === $taxonomy ) {
// get the currently featured tags.
$featured_tags = get_option( 'featured_tags' );
// if the updated term is in the array, note the array key.
$found_term = array_search( $term_id, $featured_tags, true );
if ( false !== $found_term ) {
// the updated term is a featured tag! replace it in the array, save the new array.
$featured_tags[ $found_term ] = $new_term_id;
update_option( 'featured_tags', $featured_tags );
}
}
}
add_action( 'split_shared_term', 'wporg_featured_tags_split', 10, 4 );
术语 ID 存储在帖子元中
假设您的插件在页面的帖子元数据中存储术语 ID,以便您可以显示特定页面的相关帖子。
在这种情况下,您需要使用该get_posts()
函数来获取您的页面meta_key
并更新meta_value
匹配的拆分术语 ID。
/**
* Update related posts term ID for pages
*
* @param int $term_id ID of the formerly shared term.
* @param int $new_term_id ID of the new term created for the $term_taxonomy_id.
* @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split.
* @param string $taxonomy Taxonomy for the split term.
*/
function wporg_page_related_posts_split( int $term_id, int $new_term_id, int $term_taxonomy_id, string $taxonomy ): void {
// find all the pages where meta_value matches the old term ID.
$page_ids = get_posts(
array(
'post_type' => 'page',
'fields' => 'ids',
'meta_key' => 'meta_key',
'meta_value' => $term_id,
)
);
// if such pages exist, update the term ID for each page.
if ( $page_ids ) {
foreach ( $page_ids as $id ) {
update_post_meta( $id, 'meta_key', $new_term_id, $term_id );
}
}
}
add_action( 'split_shared_term', 'wporg_page_related_posts_split', 10, 4 );
功能wp_get_split_term
_
但是,在某些情况下,术语可能会被拆分,而您的插件没有机会挂钩该split_shared_term
操作。
WordPress 4.2 存储有关已拆分的分类术语的信息,并提供wp_get_split_term()
实用函数来帮助开发人员检索此信息。
考虑上面的情况,您的插件将术语 ID 存储在名为 的选项中featured_tags
。您可能想要构建一个验证这些标签 ID 的函数(可能在插件更新时运行),以确保没有任何特色标签被拆分:
/**
* Retrieve information about split terms and udpates the featured_tags option with the new term IDs.
*
* @return void
*/
function wporg_featured_tags_check_split() {
$featured_tag_ids = get_option( 'featured_tags', array() );
// check to see whether any IDs correspond to post_tag terms that have been split.
foreach ( $featured_tag_ids as $index => $featured_tag_id ) {
$new_term_id = wp_get_split_term( $featured_tag_id, 'post_tag' );
if ( $new_term_id ) {
$featured_tag_ids[ $index ] = $new_term_id;
}
}
// save
update_option( 'featured_tags', $featured_tag_ids );
}
请注意,它wp_get_split_term()
需要两个参数,$old_term_id
并且$taxonomy
返回一个整数。
如果您需要检索与旧术语 ID 关联的所有拆分术语的列表,无论分类如何,请使用wp_get_split_terms()
。