wp_unique_term_slug()
云策文档标注
概述
wp_unique_term_slug() 函数用于确保分类法术语的 slug 全局唯一,避免重复。它通过检查现有 slug、结合父级 slug 或添加数字后缀来生成唯一标识符。
关键要点
- slug 必须在所有分类法中全局唯一,不同分类法的术语不能有相同 slug。
- 如果分类法是层级结构且术语有父级,函数会尝试将父级 slug 附加到当前 slug 以增强唯一性。
- 若仍不唯一,函数会追加递增数字(如 -2、-3)直到找到唯一 slug。
- 参数 $term 主要用于获取父级信息,以支持层级结构的 slug 生成。
- 函数返回一个确保唯一的 slug 字符串。
代码示例
function wp_unique_term_slug( $slug, $term ) {
global $wpdb;
$needs_suffix = true;
$original_slug = $slug;
// 检查 slug 是否已存在,考虑不同分类法允许重复的情况
if ( ! term_exists( $slug ) || get_option( 'db_version' ) >= 30133 && ! get_term_by( 'slug', $slug, $term->taxonomy ) ) {
$needs_suffix = false;
}
// 处理层级分类法的父级 slug
$parent_suffix = '';
if ( $needs_suffix && is_taxonomy_hierarchical( $term->taxonomy ) && ! empty( $term->parent ) ) {
$the_parent = $term->parent;
while ( ! empty( $the_parent ) ) {
$parent_term = get_term( $the_parent, $term->taxonomy );
if ( is_wp_error( $parent_term ) || empty( $parent_term ) ) {
break;
}
$parent_suffix .= '-' . $parent_term->slug;
if ( ! term_exists( $slug . $parent_suffix ) ) {
break;
}
if ( empty( $parent_term->parent ) ) {
break;
}
$the_parent = $parent_term->parent;
}
}
// 通过数字后缀确保唯一性
if ( apply_filters( 'wp_unique_term_slug_is_bad_slug', $needs_suffix, $slug, $term ) ) {
if ( $parent_suffix ) {
$slug .= $parent_suffix;
}
if ( ! empty( $term->term_id ) ) {
$query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $term->term_id );
} else {
$query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug );
}
if ( $wpdb->get_var( $query ) ) {
$num = 2;
do {
$alt_slug = $slug . "-$num";
++$num;
$slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) );
} while ( $slug_check );
$slug = $alt_slug;
}
}
return apply_filters( 'wp_unique_term_slug', $slug, $term, $original_slug );
}注意事项
- 从 WordPress 4.1 开始,允许不同分类法中有重复 slug,但同一分类法内仍需唯一。
- 函数使用 wpdb 直接查询数据库以检查 slug 唯一性,确保高效性。
- 提供了两个过滤器:wp_unique_term_slug_is_bad_slug 用于控制是否需要后缀,wp_unique_term_slug 用于修改最终返回的 slug。
- 相关函数包括 term_exists()、get_term_by()、is_taxonomy_hierarchical() 等,用于辅助 slug 验证和层级处理。
原文内容
Makes term slug unique, if it isn’t already.
Description
The $slug has to be unique global to every taxonomy, meaning that one taxonomy term can’t have a matching slug with another taxonomy term. Each slug has to be globally unique for every taxonomy.
The way this works is that if the taxonomy that the term belongs to is hierarchical and has a parent, it will append that parent to the $slug.
If that still doesn’t return a unique slug, then it tries to append a number until it finds a number that is truly unique.
The only purpose for $term is for appending a parent, if one exists.
Parameters
$slugstringrequired-
The string that will be tried for a unique slug.
$termobjectrequired-
The term object that the
$slugwill belong to.
Source
function wp_unique_term_slug( $slug, $term ) {
global $wpdb;
$needs_suffix = true;
$original_slug = $slug;
// As of 4.1, duplicate slugs are allowed as long as they're in different taxonomies.
if ( ! term_exists( $slug ) || get_option( 'db_version' ) >= 30133 && ! get_term_by( 'slug', $slug, $term->taxonomy ) ) {
$needs_suffix = false;
}
/*
* If the taxonomy supports hierarchy and the term has a parent, make the slug unique
* by incorporating parent slugs.
*/
$parent_suffix = '';
if ( $needs_suffix && is_taxonomy_hierarchical( $term->taxonomy ) && ! empty( $term->parent ) ) {
$the_parent = $term->parent;
while ( ! empty( $the_parent ) ) {
$parent_term = get_term( $the_parent, $term->taxonomy );
if ( is_wp_error( $parent_term ) || empty( $parent_term ) ) {
break;
}
$parent_suffix .= '-' . $parent_term->slug;
if ( ! term_exists( $slug . $parent_suffix ) ) {
break;
}
if ( empty( $parent_term->parent ) ) {
break;
}
$the_parent = $parent_term->parent;
}
}
// If we didn't get a unique slug, try appending a number to make it unique.
/**
* Filters whether the proposed unique term slug is bad.
*
* @since 4.3.0
*
* @param bool $needs_suffix Whether the slug needs to be made unique with a suffix.
* @param string $slug The slug.
* @param object $term Term object.
*/
if ( apply_filters( 'wp_unique_term_slug_is_bad_slug', $needs_suffix, $slug, $term ) ) {
if ( $parent_suffix ) {
$slug .= $parent_suffix;
}
if ( ! empty( $term->term_id ) ) {
$query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $term->term_id );
} else {
$query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug );
}
if ( $wpdb->get_var( $query ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$num = 2;
do {
$alt_slug = $slug . "-$num";
++$num;
$slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) );
} while ( $slug_check );
$slug = $alt_slug;
}
}
/**
* Filters the unique term slug.
*
* @since 4.3.0
*
* @param string $slug Unique term slug.
* @param object $term Term object.
* @param string $original_slug Slug originally passed to the function for testing.
*/
return apply_filters( 'wp_unique_term_slug', $slug, $term, $original_slug );
}
Hooks
- apply_filters( ‘wp_unique_term_slug’, string $slug, object $term, string $original_slug )
-
Filters the unique term slug.
- apply_filters( ‘wp_unique_term_slug_is_bad_slug’, bool $needs_suffix, string $slug, object $term )
-
Filters whether the proposed unique term slug is bad.
Changelog
| Version | Description |
|---|---|
| 2.3.0 | Introduced. |