函数文档

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.