此处提供这些信息仅供历史参考。如果您不关心 2015 年之前术语的工作方式,可以跳过本节。

WordPress 4.2 之前

不同分类法中具有相同 slugs 的术语共享单个术语 ID。例如,具有 slug“news”的标签和分类拥有相同的术语 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 的页面,并更新与拆分的术语 ID 匹配的 meta_value。

/**
 * 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 钩子是处理术语 ID 变更的首选方法。

然而,可能会出现您的插件没有机会钩入 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()。