WP_Sitemaps
云策文档标注
概述
WP_Sitemaps 是 WordPress 5.5.0 引入的核心类,用于管理 XML 站点地图的生成、注册和渲染。它整合了注册表、索引和渲染器组件,提供完整的站点地图功能。
关键要点
- WP_Sitemaps 类负责初始化站点地图系统,包括注册重写规则、提供者和渲染逻辑。
- 通过 WP_Sitemaps_Registry 管理提供者(如 posts、taxonomies、users),WP_Sitemaps_Index 处理索引,WP_Sitemaps_Renderer 负责输出。
- 站点地图的启用状态由 blog_public 选项和 wp_sitemaps_enabled 过滤器控制,禁用时仍注册重写规则以返回 404。
- 提供方法如 init() 启动功能,register_rewrites() 设置 URL 路由,render_sitemaps() 基于查询变量渲染站点地图或样式表。
- 支持自动添加到 robots.txt(通过 add_robots()),并包含已弃用的重定向方法 redirect_sitemapxml()。
代码示例
// 示例:初始化 WP_Sitemaps 并检查启用状态
$sitemaps = new WP_Sitemaps();
$sitemaps->init();
if ( $sitemaps->sitemaps_enabled() ) {
// 站点地图已启用,可执行相关操作
}
// 示例:注册自定义提供者(需扩展 WP_Sitemaps_Provider)
$provider = new Custom_Sitemaps_Provider();
$sitemaps->registry->add_provider( 'custom', $provider );注意事项
- WP_Sitemaps::redirect_sitemapxml 方法自 WordPress 6.7.0 起已弃用,建议使用 WP_Rewrite::rewrite_rules() 替代。
- 渲染站点地图时,如果未找到 URL 列表,会自动设置 404 状态并退出。
- 站点地图的样式表通过 WP_Sitemaps_Stylesheet 类处理,支持 sitemap 和 index 两种类型。
原文内容
Class WP_Sitemaps.
Methods
| Name | Description |
|---|---|
| WP_Sitemaps::__construct | WP_Sitemaps constructor. |
| WP_Sitemaps::add_robots | Adds the sitemap index to robots.txt. |
| WP_Sitemaps::init | Initiates all sitemap functionality. |
| WP_Sitemaps::redirect_sitemapxml | Redirects a URL to the wp-sitemap.xml — deprecated |
| WP_Sitemaps::register_rewrites | Registers sitemap rewrite tags and routing rules. |
| WP_Sitemaps::register_sitemaps | Registers and sets up the functionality for all supported sitemaps. |
| WP_Sitemaps::render_sitemaps | Renders sitemap templates based on rewrite rules. |
| WP_Sitemaps::sitemaps_enabled | Determines whether sitemaps are enabled or not. |
Source
class WP_Sitemaps {
/**
* The main index of supported sitemaps.
*
* @since 5.5.0
*
* @var WP_Sitemaps_Index
*/
public $index;
/**
* The main registry of supported sitemaps.
*
* @since 5.5.0
*
* @var WP_Sitemaps_Registry
*/
public $registry;
/**
* An instance of the renderer class.
*
* @since 5.5.0
*
* @var WP_Sitemaps_Renderer
*/
public $renderer;
/**
* WP_Sitemaps constructor.
*
* @since 5.5.0
*/
public function __construct() {
$this->registry = new WP_Sitemaps_Registry();
$this->renderer = new WP_Sitemaps_Renderer();
$this->index = new WP_Sitemaps_Index( $this->registry );
}
/**
* Initiates all sitemap functionality.
*
* If sitemaps are disabled, only the rewrite rules will be registered
* by this method, in order to properly send 404s.
*
* @since 5.5.0
*/
public function init() {
// These will all fire on the init hook.
$this->register_rewrites();
add_action( 'template_redirect', array( $this, 'render_sitemaps' ) );
if ( ! $this->sitemaps_enabled() ) {
return;
}
$this->register_sitemaps();
// Add additional action callbacks.
add_filter( 'robots_txt', array( $this, 'add_robots' ), 0, 2 );
}
/**
* Determines whether sitemaps are enabled or not.
*
* @since 5.5.0
*
* @return bool Whether sitemaps are enabled.
*/
public function sitemaps_enabled() {
$is_enabled = (bool) get_option( 'blog_public' );
/**
* Filters whether XML Sitemaps are enabled or not.
*
* When XML Sitemaps are disabled via this filter, rewrite rules are still
* in place to ensure a 404 is returned.
*
* @see WP_Sitemaps::register_rewrites()
*
* @since 5.5.0
*
* @param bool $is_enabled Whether XML Sitemaps are enabled or not.
* Defaults to true for public sites.
*/
return (bool) apply_filters( 'wp_sitemaps_enabled', $is_enabled );
}
/**
* Registers and sets up the functionality for all supported sitemaps.
*
* @since 5.5.0
*/
public function register_sitemaps() {
$providers = array(
'posts' => new WP_Sitemaps_Posts(),
'taxonomies' => new WP_Sitemaps_Taxonomies(),
'users' => new WP_Sitemaps_Users(),
);
/* @var WP_Sitemaps_Provider $provider */
foreach ( $providers as $name => $provider ) {
$this->registry->add_provider( $name, $provider );
}
}
/**
* Registers sitemap rewrite tags and routing rules.
*
* @since 5.5.0
*/
public function register_rewrites() {
// Add rewrite tags.
add_rewrite_tag( '%sitemap%', '([^?]+)' );
add_rewrite_tag( '%sitemap-subtype%', '([^?]+)' );
// Register index route.
add_rewrite_rule( '^wp-sitemap.xml$', 'index.php?sitemap=index', 'top' );
// Register rewrites for the XSL stylesheet.
add_rewrite_tag( '%sitemap-stylesheet%', '([^?]+)' );
add_rewrite_rule( '^wp-sitemap.xsl$', 'index.php?sitemap-stylesheet=sitemap', 'top' );
add_rewrite_rule( '^wp-sitemap-index.xsl$', 'index.php?sitemap-stylesheet=index', 'top' );
// Register routes for providers.
add_rewrite_rule(
'^wp-sitemap-([a-z]+?)-([a-zd_-]+?)-(d+?).xml$',
'index.php?sitemap=$matches[1]&sitemap-subtype;=$matches[2]&paged;=$matches[3]',
'top'
);
add_rewrite_rule(
'^wp-sitemap-([a-z]+?)-(d+?).xml$',
'index.php?sitemap=$matches[1]&paged;=$matches[2]',
'top'
);
}
/**
* Renders sitemap templates based on rewrite rules.
*
* @since 5.5.0
*
* @global WP_Query $wp_query WordPress Query object.
*/
public function render_sitemaps() {
global $wp_query;
$sitemap = sanitize_text_field( get_query_var( 'sitemap' ) );
$object_subtype = sanitize_text_field( get_query_var( 'sitemap-subtype' ) );
$stylesheet_type = sanitize_text_field( get_query_var( 'sitemap-stylesheet' ) );
$paged = absint( get_query_var( 'paged' ) );
// Bail early if this isn't a sitemap or stylesheet route.
if ( ! ( $sitemap || $stylesheet_type ) ) {
return;
}
if ( ! $this->sitemaps_enabled() ) {
$wp_query->set_404();
status_header( 404 );
return;
}
// Render stylesheet if this is stylesheet route.
if ( $stylesheet_type ) {
$stylesheet = new WP_Sitemaps_Stylesheet();
$stylesheet->render_stylesheet( $stylesheet_type );
exit;
}
// Render the index.
if ( 'index' === $sitemap ) {
$sitemap_list = $this->index->get_sitemap_list();
$this->renderer->render_index( $sitemap_list );
exit;
}
$provider = $this->registry->get_provider( $sitemap );
if ( ! $provider ) {
return;
}
if ( empty( $paged ) ) {
$paged = 1;
}
$url_list = $provider->get_url_list( $paged, $object_subtype );
// Force a 404 and bail early if no URLs are present.
if ( empty( $url_list ) ) {
$wp_query->set_404();
status_header( 404 );
return;
}
$this->renderer->render_sitemap( $url_list );
exit;
}
/**
* Redirects a URL to the wp-sitemap.xml
*
* @since 5.5.0
* @deprecated 6.7.0 Deprecated in favor of <a href="https://developer.wordpress.org/reference/classes/WP_Rewrite/rewrite_rules/">WP_Rewrite::rewrite_rules()</a>
*
* @param bool $bypass Pass-through of the pre_handle_404 filter value.
* @param WP_Query $query The WP_Query object.
* @return bool Bypass value.
*/
public function redirect_sitemapxml( $bypass, $query ) {
_deprecated_function( __FUNCTION__, '6.7.0' );
// If a plugin has already utilized the pre_handle_404 function, return without action to avoid conflicts.
if ( $bypass ) {
return $bypass;
}
// 'pagename' is for most permalink types, name is for when the %postname% is used as a top-level field.
if ( 'sitemap-xml' === $query->get( 'pagename' )
|| 'sitemap-xml' === $query->get( 'name' )
) {
wp_safe_redirect( $this->index->get_index_url() );
exit();
}
return $bypass;
}
/**
* Adds the sitemap index to robots.txt.
*
* @since 5.5.0
*
* @param string $output robots.txt output.
* @param bool $is_public Whether the site is public.
* @return string The robots.txt output.
*/
public function add_robots( $output, $is_public ) {
if ( $is_public ) {
$output .= "nSitemap: " . esc_url( $this->index->get_index_url() ) . "n";
}
return $output;
}
}
Changelog
| Version | Description |
|---|---|
| 5.5.0 | Introduced. |