wp_old_slug_redirect()
云策文档标注
概述
wp_old_slug_redirect() 是一个 WordPress 核心函数,用于在页面返回 404 错误时,尝试将旧的 slug 重定向到正确的永久链接。它通过查询变量和辅助函数查找匹配的帖子 ID,并执行 301 永久重定向。
关键要点
- 函数仅在 is_404() 为真且查询变量 'name' 非空时触发重定向逻辑。
- 通过 get_query_var() 推断帖子类型,并排除分层帖子类型(如页面)的重定向。
- 使用 _find_post_by_old_slug() 和 _find_post_by_old_date() 查找重定向目标帖子 ID。
- 提供两个过滤器钩子:old_slug_redirect_post_id 和 old_slug_redirect_url,允许开发者自定义重定向 ID 和 URL。
- 支持分页和嵌入内容的 URL 处理,最终使用 wp_redirect() 进行 301 重定向。
代码示例
function wp_old_slug_redirect() {
if ( is_404() && '' !== get_query_var( 'name' ) ) {
// Guess the current post type based on the query vars.
if ( get_query_var( 'post_type' ) ) {
$post_type = get_query_var( 'post_type' );
} elseif ( get_query_var( 'attachment' ) ) {
$post_type = 'attachment';
} elseif ( get_query_var( 'pagename' ) ) {
$post_type = 'page';
} else {
$post_type = 'post';
}
if ( is_array( $post_type ) ) {
if ( count( $post_type ) > 1 ) {
return;
}
$post_type = reset( $post_type );
}
// Do not attempt redirect for hierarchical post types.
if ( is_post_type_hierarchical( $post_type ) ) {
return;
}
$id = _find_post_by_old_slug( $post_type );
if ( ! $id ) {
$id = _find_post_by_old_date( $post_type );
}
/**
* Filters the old slug redirect post ID.
*
* @since 4.9.3
*
* @param int $id The redirect post ID.
*/
$id = apply_filters( 'old_slug_redirect_post_id', $id );
if ( ! $id ) {
return;
}
$link = get_permalink( $id );
if ( get_query_var( 'paged' ) > 1 ) {
$link = user_trailingslashit( trailingslashit( $link ) . 'page/' . get_query_var( 'paged' ) );
} elseif ( is_embed() ) {
$link = user_trailingslashit( trailingslashit( $link ) . 'embed' );
}
/**
* Filters the old slug redirect URL.
*
* @since 4.4.0
*
* @param string $link The redirect URL.
*/
$link = apply_filters( 'old_slug_redirect_url', $link );
if ( ! $link ) {
return;
}
wp_redirect( $link, 301 ); // Permanent redirect.
exit;
}
}注意事项
- 该函数自 WordPress 2.1.0 版本引入,是处理旧 slug 重定向的标准方法。
- 重定向仅适用于非分层帖子类型(如文章),页面等分层类型不会触发重定向。
- 开发者可以通过过滤器钩子 old_slug_redirect_post_id 和 old_slug_redirect_url 自定义重定向行为。
- 函数内部使用 exit 语句终止执行,确保重定向后不会继续处理后续代码。
原文内容
Redirect old slugs to the correct permalink.
Description
Attempts to find the current slug from the past slugs.
Source
function wp_old_slug_redirect() {
if ( is_404() && '' !== get_query_var( 'name' ) ) {
// Guess the current post type based on the query vars.
if ( get_query_var( 'post_type' ) ) {
$post_type = get_query_var( 'post_type' );
} elseif ( get_query_var( 'attachment' ) ) {
$post_type = 'attachment';
} elseif ( get_query_var( 'pagename' ) ) {
$post_type = 'page';
} else {
$post_type = 'post';
}
if ( is_array( $post_type ) ) {
if ( count( $post_type ) > 1 ) {
return;
}
$post_type = reset( $post_type );
}
// Do not attempt redirect for hierarchical post types.
if ( is_post_type_hierarchical( $post_type ) ) {
return;
}
$id = _find_post_by_old_slug( $post_type );
if ( ! $id ) {
$id = _find_post_by_old_date( $post_type );
}
/**
* Filters the old slug redirect post ID.
*
* @since 4.9.3
*
* @param int $id The redirect post ID.
*/
$id = apply_filters( 'old_slug_redirect_post_id', $id );
if ( ! $id ) {
return;
}
$link = get_permalink( $id );
if ( get_query_var( 'paged' ) > 1 ) {
$link = user_trailingslashit( trailingslashit( $link ) . 'page/' . get_query_var( 'paged' ) );
} elseif ( is_embed() ) {
$link = user_trailingslashit( trailingslashit( $link ) . 'embed' );
}
/**
* Filters the old slug redirect URL.
*
* @since 4.4.0
*
* @param string $link The redirect URL.
*/
$link = apply_filters( 'old_slug_redirect_url', $link );
if ( ! $link ) {
return;
}
wp_redirect( $link, 301 ); // Permanent redirect.
exit;
}
}
Hooks
- apply_filters( ‘old_slug_redirect_post_id’, int $id )
-
Filters the old slug redirect post ID.
- apply_filters( ‘old_slug_redirect_url’, string $link )
-
Filters the old slug redirect URL.
Changelog
| Version | Description |
|---|---|
| 2.1.0 | Introduced. |