WordPress как на ладони
rgbcode is looking for WordPress developers.

Карта Сайта WordPress

В Версии WordPress 5.5 была наконец-то добавлена поддержка карты сайта в ядро. Плагин Google XML Sitemaps и ему подобные больше не нужны.

Знакомство

Главная страница Карты Сайта WordPress находится по адресу /wp-sitemap.xml. Она содержит ссылки на карты ссылок. Альтернативные адреса с которых отредиректит на правильный адрес: sitemap.xml или /sitemap-xml.

И уже каждая карта ссылок содержит ссылки на страницы сайта.

Что по умолчанию попадает в Карту сайта?

Только публичные типы постов или таксономий, а также страницы постов авторов. Публичный тип или нет определяется параметрами public и publicly_queryable при регистрации типа записи или таксономии.

Максимальное кол-во ссылок в Карте

Главная (index) страница может содержать максимум 50 000 карт (ссылок на карты). Это значение изменить нельзя, оно находится в приватном свойстве WP_Sitemaps_Index::$max_sitemaps.

Каждая карта ссылок может содержать максимум 2 000 ссылок на странице. Это значение меняется через хук wp_sitemaps_max_urls:

# Изменим макс. кол-во ссылок в каждой карте ссылок.
# Возможные значение $object_type: post, term, user
add_filter( 'wp_sitemaps_max_urls', 'kama_sitemap_max_urls', 10, 2 );
function kama_sitemap_max_urls( $num, $object_type ){
	return 1000;
}

Изменение кол-ва макс. ссылок влияет на кол-во ссылок пагинации на главной странице Карты сайта. Например, если у нас всего 500 постов, то по умолчанию будет всего одна карта ссылок для всех постов. Но если мы изменим максимум на 100. То на индексной странице появится 5 ссылок на Карты постов.

Не работает Карта сайта WordPress, 501 ошибка?

XML Карта Сайта WP работает на основе PHP расширения SimpleXML. Если его нет у вас на сервере, то при переходе на страницу карты сайта вы получите 501 ошибку.

Ссылка на карту сайта в файле robots.txt

Ссылка https://домен/wp-sitemap.xml добавляется в конец файла robots.txt автоматически. Но только, если у вас нет физического файла robots.txt в корне сайта. Т.е. robots.txt должен создаваться динамически. Подробнее о динамическом файле robots, читайте в функции do_robots().

Пример правильного создания динамического файла robots.txt для WordPress смотрите по этой ссылке.

Отключение Карты сайта WordPress

Если на сайте установлен плагин или код, который уже создает карту сайта и Карта сайта от WordPress уже не нужна, то её можно отключить. Для этого вставьте следующий код в functions.php темы, в код плагина или куда-либо еще (впрочем, скорее всего, ваш плагин это уже сделал).

add_filter( 'wp_sitemaps_enabled', '__return_false' );

Теперь, если перейти по адресу /wp-sitemap.xml вы увидите 404 страницу.

Заметка: такое отключение не удаляет правила перезаписи для карт сайта, так как они нужны чтобы отдавать нужные ответы при отключенной карте сайта. Подробнее здесь.

Обратите внимание, что карта сайта WordPress отключается автоматически, если в настройках «Чтение» есть галочка «Попросить поисковые системы не индексировать сайт».

Добавление элементов в карту сайта

Чтобы добавить тип записи или таксономию в карту сайта WordPress, нужно сделать их публичными, для этого при регистрации нужно установить в true параметры public и publicly_queryable.

Чтобы добавить произвольные ссылки в карту сайта, нужно создать свой Провайдер.

Удаление элементов Карты сайта

Из коробки в WP есть три провайдера (поставщика) карт сайтов для разных типов: записи, таксономии, пользователи:

Удалять можно как самого провайдера карт сайтов, так и отдельный тип (отдельную карту «внутри» провайдера) или вообще отдельный элемент типа (ссылку «внутри» карты). Рассмотрим на примере таксономий. Можно отключить провайдера «taxonomies» и тогда все таксономий исчезнут из карты сайта, можно отключить отдельную таксономию и оставить остальные таксономии, или можно исключить отдельную рубрику (элемент) таксономии из списка ссылок.

Отключение Провайдера целиком (всех таксономий, юзеров, типов постов)

Провайдер - это общее понятие, которое включает в себя все типы. Например

  • провайдер типа записи включает все типы записей.
  • провайдер таксономии включает все типы таксономий.

Если отключить провайдера целиком, из карты сайта будут удалены все типы, например если отключить провайдера таксономий, то все типа таксономий (рубрики, метки, архивы пользователей) будут исключены из карты сайта.

# Отключение провайдера карт сайтов: пользователи и таксономии
add_filter( 'wp_sitemaps_add_provider', 'kama_remove_sitemap_provider', 10, 2 );

function kama_remove_sitemap_provider( $provider, $name ){

	$remove_providers = [ 'users', 'taxonomies' ];

	// отключаем архивы пользователей
	if( in_array( $name, $remove_providers ) ){
		return false;
	}

	return $provider;
}

Отключение типа записи (поста, страницы)

Например в карте сайта нам не нужен тип записи page.

# Удалим тип записи из карты сайта
add_filter( 'wp_sitemaps_post_types', 'wpkama_remove_sitemaps_post_types' );

function wpkama_remove_sitemaps_post_types( $post_types ){

	unset( $post_types['page'] );

	return $post_types;
}

Отключение таксономии (рубрики, метки)

Например в карте сайта нам не нужны метки (таксономия post_tag).

# Удалим таксономии из карты сайта
add_filter( 'wp_sitemaps_taxonomies', 'wpkama_remove_sitemaps_taxonomies' );

function wpkama_remove_sitemaps_taxonomies( $taxonomies ){

	unset( $taxonomies['post_tag'] );

	return $taxonomies;
}

Исключение отдельных url (url записи, рубрики, метки)

Элементы исключаются путем изменения параметров запроса WP_Query, WP_Term_Query через специальные хуки.

Заметка: Если после исключения отдельных элементов в карте сайта вообще не остается элементов для данного типа или провайдера, то тип или провайдер будет полностью исключен из карты сайта.

Удалим отдельные Записи из Карты сайта

Например посты с ID 12 и 24 не нужны нам в карте сайта (пусть они имеют метатег noindex,
но в карте появляются), исключим их из Карты сайта.

См. хук wp_sitemaps_posts_query_args и все возможные параметры в WP_Query().

add_filter( 'wp_sitemaps_posts_query_args', 'kama_sitemaps_posts_query_args', 10, 2 );
function kama_sitemaps_posts_query_args( $args, $post_type ){

	if( 'post' !== $post_type ){
		return $args;
	}

	// учтем что этот параметр может быть уже установлен
	if( ! isset( $args['post__not_in'] ) ){
		$args['post__not_in'] = array();
	}

	// Исключаем посты
	foreach( [ 12, 24 ] as $post_id ){
		$args['post__not_in'][] = $post_id;
	}

	return $args;
}

Удалим Термины из Карты сайта

Например термины с ID 12 и 24 из таксономии cities имеют метатег noindex, исключим их из Карты сайта.

См. хук wp_sitemaps_taxonomies_query_args и все возможные параметры в get_terms().

add_filter( 'wp_sitemaps_taxonomies_query_args', 'kama_sitemaps_taxonomies_query_args', 10, 2 );
function kama_sitemaps_taxonomies_query_args( $args, $taxonomy ){

	if( 'cities' !== $taxonomy ){
		return $args;
	}

	// учтем что этот параметр может быть уже установлен
	if( ! isset( $args['exclude'] ) ){
		$args['exclude'] = array();
	}

	// Исключаем термины
	$args['exclude'] = array_merge( $args['exclude'], [ 12, 24 ] );

	return $args;
}

Удалим отдельных Юзеров из Карты сайта

Например нам не нужны юзеры с ID 12, 24.

См. хук wp_sitemaps_users_query_args и все возможные параметры в get_users().

add_filter( 'wp_sitemaps_users_query_args', 'kama_sitemaps_users_query_args' );
function kama_sitemaps_users_query_args( $args ){

	// учтем что этот параметр может быть уже установлен
	if( ! isset( $args['exclude'] ) ){
		$args['exclude'] = array();
	}

	// Исключаем юзеров
	$args['exclude'] = array_merge( $args['exclude'], [ 12, 24 ] );

	return $args;
}

Как проверить Включена ли карта сайта

Чтобы узнать Включена ли карта сайта, используйте такую проверку:

$is_sitemaps_enabled = wp_sitemaps_get_server()->sitemaps_enabled();

if( $is_sitemaps_enabled ){
	// карты сайта WP работают
}
else{
	// карты сайта WP отключены
}

Как проверить Находимся ли мы на странице карты сайта?

Как ни странно, но готовой функции вроде is_sitemap() или is_sitemap_page() в WordPress НЕТ (справедливо для WP 6.1).

Однако сделать это не сложно. Для этого нужно проверить текущий параметр запроса (это внутренний параметр, который устанавливается на хуке wp

/**
 * Checks if it is WordPress sitemap page.
 *
 * @return bool
 */
function is_sitemap_page(){
	global $wp_version;

	if( ! did_action( 'parse_request' ) ){
		_doing_it_wrong( __FUNCTION__, 'Can`t be called before `parse_request` hook.', $wp_version );

		return false;
	}

	return (bool) sanitize_text_field( get_query_var( 'sitemap' ) );
}

Пример использования:

add_action( 'wp', function(){

	if( is_sitemap_page() ){
		// это страница карты сайта.
	}
} );

Дополнительные поля (теги) для Карты сайта

Добавим все дополнительные поддерживаемые теги для Карт записей (постов).

add_filter( 'wp_sitemaps_posts_entry', 'wpkama_sitemaps_posts_entry', 10, 2 );
function wpkama_sitemaps_posts_entry( $entry, $post ){

	$entry['lastmod']    = get_the_modified_date( 'c', $post );
	$entry['priority']   = 0.8;
	$entry['changefreq'] = 'weekly';

	return $entry;
}

Получим:

Рассмотрим все подробнее

Протокол sitemaps поддерживает четыре атрибута для каждого элемента <url> карты сайта (по умолчанию в WP используется только <loc>). Остальные можно добавить через фильтры.

Вот что выводится по умолчанию в WordPress:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

   <url>
	  <loc>http://www.example.com/</loc>
   </url>

</urlset>

Вот что поддерживается протоколом:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

   <url>
	  <loc>http://www.example.com/</loc>
	  <lastmod>2005-01-01</lastmod>
	  <changefreq>monthly</changefreq>
	  <priority>0.8</priority>
   </url>

</urlset>
loc(Обязательный)
URL-адрес страницы. Этот URL должен начинаться с протокола (например, http). Должен быть меньше 2048 символов.
lastmod

Дата последнего изменения файла. Дата должна быть в формате W3C Datetime:

  • YYYY - 1997
  • YYYY-MM - 1997-07
  • YYYY-MM-DD - 1997-07-16
  • YYYY-MM-DDThh:mmTZD - 1997-07-16T19:20+01:00
  • YYYY-MM-DDThh:mm:ssTZD - 1997-07-16T19:20:30+01:00

Обратите внимание, что этот тег независим от заголовка If-Modified-Since (304), который может возвращать сервер, и поисковые системы могут использовать информацию из обоих источников по-разному.

changefreq

Как часто страница может меняться. Это значение предоставляет общую информацию для поисковых систем. Поисковики могут игнорировать эту информацию и заходить на страницу чаще или реже. Возможные значения:

  • always - используется для страниц, которые изменяются при каждом обращении к ним.
  • hourly
  • daily
  • weekly
  • monthly
  • yearly
  • never - используется для архивированных URL-адресов.
priority

Важность этого URL по отношению к другим URL-адресам. Значение указывается от 0.0 до 1.0. Это значение не влияет на то, как ваши страницы сравниваются со страницами на других сайтах — оно только позволяет поисковым системам узнать, какие страницы вы считаете наиболее важными. Стандартный приоритет равен 0.5.

Обратите внимание, что приоритет, который вы назначаете странице, вряд ли повлияет на положение Ваших URL-адресов на страницах результатов поисковой системы. Поисковые системы могут использовать эту информацию при выборе между URL-адресами на одном и том же сайте, поэтому вы можете использовать этот тег, чтобы увеличить вероятность того, что ваши самые важные страницы будут присутствовать в поисковом индексе.

Также, обратите внимание, что присвоение высокого приоритета всем URL-адресам вряд ли что-то улучшит. Поскольку приоритет является относительным, он используется только для выбора ботом какую страницу посетить в первую очередь между URL-адресами на вашем сайте.

Все фильтры доп. XML тегов  
wp_sitemaps_posts_entry Доп теги (поля) для URL Карт сайта записей (постов).
wp_sitemaps_taxonomies_entry Доп теги (поля) для URL Карт сайта таксономий.
wp_sitemaps_users_entry Доп теги (поля) для URL Карт сайта юзеров.
wp_sitemaps_index_entry Доп теги (поля) для URL главной страницы карты сайта.

Классы, Функции, Хуки

Для управления/изменения Карты сайта есть набор функций, классов и хуков. Ниже приведен список всех Функций, классов и хуков, которые связаны с Картой сайта WordPress.

Функции  
wp_sitemaps_get_server() Получает текущий экземпляр сервера Sitemaps.
wp_get_sitemap_providers() Получает массив поставщиков карт сайта.
wp_register_sitemap_provider() Регистрирует нового поставщика карты сайта.
wp_sitemaps_get_max_urls() Возвращает максимальное количество URL-адресов для карты сайта.
Классы  
WP_Sitemaps{} Основной класс отвечает за настройку перезаписей и регистрацию всех поставщиков.
WP_Sitemaps_Index{} Создает главную страницу sitemap, на которой перечислены ссылки на все карты сайтов.
WP_Sitemaps_Provider{} Базовый класс для расширения поставщиков карт сайта. Также содержит общие функциональные возможности.
WP_Sitemaps_Registry{} Обрабатывает регистрацию поставщиков карт сайта.
WP_Sitemaps_Renderer{} Отвечает за рендеринг данных sitemap в XML в соответствии с протоколом sitemap.
WP_Sitemaps_Stylesheet{} Предоставляет таблицы стилей XSL для стилизации всех карт сайта.
WP_Sitemaps_Posts{} Провайдер. Создает карты сайтов для типа объекта записи и его подтипов (пользовательские типы записей).
WP_Sitemaps_Taxonomies{} Провайдер. Создает карты сайтов для типа объекта таксономия и его подтипов (пользовательские таксономии).
WP_Sitemaps_Users{} Провайдер. Создает карты сайтов для типа объекта пользователь.
Общие хуки  
wp_sitemaps_enabled Фильтрует, включены ли XML-карты сайтов или нет.
wp_sitemaps_max_urls Фильтрует максимальное количество URL-адресов, отображаемых на карте сайта.
wp_sitemaps_init Срабатывает при инициализации карт сайтов.
wp_sitemaps_index_entry Фильтрует запись sitemap для главной страницы.
Хуки Поставщиков (Providers)  
wp_sitemaps_add_provider Фильтрует поставщика sitemap перед его добавлением.
wp_sitemaps_post_types Фильтрует типы записей для включения в карты сайтов.
wp_sitemaps_posts_entry Фильтрует теги <url> записи.
wp_sitemaps_posts_show_on_front_entry Фильтрует теги <url> домашней страницы.
wp_sitemaps_posts_query_args Фильтрует параметры запроса WP_Query.
wp_sitemaps_posts_pre_url_list Фильтрует список URL-адресов до его создания (замыкание).
wp_sitemaps_posts_pre_max_num_pages Фильтрует макс. кол-во страниц страниц постов (замыкание).
wp_sitemaps_taxonomies Фильтрует список таксономий.
wp_sitemaps_taxonomies_entry Фильтрует теги <url> элемента таксономии.
wp_sitemaps_taxonomies_query_args Фильтрует параметры запроса получения элементов таксономии.
wp_sitemaps_taxonomies_pre_url_list Фильтрует список URL таксономий до создания (замыкание).
wp_sitemaps_taxonomies_pre_max_num_pages Фильтрует макс. кол-во страниц таксономий (замыкание).
wp_sitemaps_users_entry Фильтрует теги <url> пользователя.
wp_sitemaps_users_query_args Фильтры параметры запроса юзеров.
wp_sitemaps_users_pre_url_list Фильтрует список URL пользователей до создания (замыкание).
wp_sitemaps_users_pre_max_num_pages Фильтрует макс. кол-во страниц юзеров (замыкание).

Заметки

Оптимизируем WP_Query внутри карт сайта

С версии WP 6.1 была добавлена оптимизация WP_Query. Поэтому, если у вас установлен плагин постоянного объектного кэширования, например Redis, то в такой оптимизации нет смысла.

Подробнее про оптимизацию: https://make.wordpress.org/core/2022/10/07/improvements-to-wp_query-performance-in-6-1/

По-умолчанию для вывода постов всех типов, класс WP_Sitemaps_Posts{} использует WP_Query и в результат отдаёт массив с объектами постов, тогда как в любом сценарии нам хватит одного лишь ID поста.

Если у вас очень большое количество постов какого-либо типа, то вы можете обнаружить долгую генерацию отдельных карт. Код ниже позволяет изменить WP_Query, заставив его отдавать массив только с ID, что улучшит скорость генерации страницы и снизит нагрузку.

// Добавляем фильтр, чтобы WP_Query отдавал только массив id постов
add_filter( 'wp_sitemaps_posts_query_args', 'optimize_sitemap_posts_query', 10, 1 );
function optimize_sitemap_posts_query( $args ){
	$args['fields'] = 'ids';

	return $args;
}
47 комментариев
Полезные 6Вопросы 3 Все
    Войти