wp_filter_wp_template_unique_post_slug()
云策文档标注
概述
wp_filter_wp_template_unique_post_slug() 是一个 WordPress 过滤器函数,用于为模板(wp_template 和 wp_template_part)生成唯一的 slug。它通过检查同一主题下是否存在重复的 slug,并在必要时添加后缀来确保唯一性。
关键要点
- 函数仅适用于 wp_template 和 wp_template_part 类型的文章,其他类型直接返回过滤后的 slug。
- 通过 WP_Query 查询同一主题下是否存在相同 slug 的文章,避免冲突。
- 如果发现重复,函数会生成带数字后缀的新 slug,直到唯一为止。
- 使用 get_stylesheet() 或 get_the_terms() 获取主题信息,优先考虑已保存的 wp_theme 分类术语。
代码示例
function wp_filter_wp_template_unique_post_slug( $override_slug, $slug, $post_id, $post_status, $post_type ) {
if ( 'wp_template' !== $post_type && 'wp_template_part' !== $post_type ) {
return $override_slug;
}
if ( ! $override_slug ) {
$override_slug = $slug;
}
$theme = get_stylesheet();
$terms = get_the_terms( $post_id, 'wp_theme' );
if ( $terms && ! is_wp_error( $terms ) ) {
$theme = $terms[0]->name;
}
$check_query_args = array(
'post_name__in' => array( $override_slug ),
'post_type' => $post_type,
'posts_per_page' => 1,
'no_found_rows' => true,
'post__not_in' => array( $post_id ),
'tax_query' => array(
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme,
),
),
);
$check_query = new WP_Query( $check_query_args );
$posts = $check_query->posts;
if ( count( $posts ) > 0 ) {
$suffix = 2;
do {
$query_args = $check_query_args;
$alt_post_name = _truncate_post_slug( $override_slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
$query_args['post_name__in'] = array( $alt_post_name );
$query = new WP_Query( $query_args );
++$suffix;
} while ( count( $query->posts ) > 0 );
$override_slug = $alt_post_name;
}
return $override_slug;
}注意事项
- 函数在 WordPress 5.8.0 版本中引入,主要用于模板系统。
- 当前实现仅考虑当前激活主题,对于多主题环境的支持有限,未来可能需要更新。
- 使用 _truncate_post_slug() 确保生成的 slug 长度不超过限制。
原文内容
Generates a unique slug for templates.
Parameters
$override_slugstringrequired-
The filtered value of the slug (starts as
nullfrom apply_filter). $slugstringrequired-
The original/un-filtered slug (post_name).
$post_idintrequired-
Post ID.
$post_statusstringrequired-
No uniqueness checks are made if the post is still draft or pending.
$post_typestringrequired-
Post type.
Source
function wp_filter_wp_template_unique_post_slug( $override_slug, $slug, $post_id, $post_status, $post_type ) {
if ( 'wp_template' !== $post_type && 'wp_template_part' !== $post_type ) {
return $override_slug;
}
if ( ! $override_slug ) {
$override_slug = $slug;
}
/*
* Template slugs must be unique within the same theme.
* TODO - Figure out how to update this to work for a multi-theme environment.
* Unfortunately using `get_the_terms()` for the 'wp-theme' term does not work
* in the case of new entities since is too early in the process to have been saved
* to the entity. So for now we use the currently activated theme for creation.
*/
$theme = get_stylesheet();
$terms = get_the_terms( $post_id, 'wp_theme' );
if ( $terms && ! is_wp_error( $terms ) ) {
$theme = $terms[0]->name;
}
$check_query_args = array(
'post_name__in' => array( $override_slug ),
'post_type' => $post_type,
'posts_per_page' => 1,
'no_found_rows' => true,
'post__not_in' => array( $post_id ),
'tax_query' => array(
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme,
),
),
);
$check_query = new WP_Query( $check_query_args );
$posts = $check_query->posts;
if ( count( $posts ) > 0 ) {
$suffix = 2;
do {
$query_args = $check_query_args;
$alt_post_name = _truncate_post_slug( $override_slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
$query_args['post_name__in'] = array( $alt_post_name );
$query = new WP_Query( $query_args );
++$suffix;
} while ( count( $query->posts ) > 0 );
$override_slug = $alt_post_name;
}
return $override_slug;
}
Changelog
| Version | Description |
|---|---|
| 5.8.0 | Introduced. |