Створення Провайдера для Картки сайту
Система Карти сайту WordPress, як і багато інших частин дозволяє досить просто розширювати функціональність і додавати довільні посилання в існуючу Карту сайту. Нижче розглянемо, як це робиться.
Що кастомне автоматично додається до Карти сайту?
Якщо ви створюєте додаткові (кастомні) типи записів або таксономії, ці сутності автоматично потраплять до Карти сайту WordPress. Єдине що для цього потрібно, щоб новий тип запису або таксономія були «публічні»: мали параметри publicly_queryable = true . Ці параметри вказуються під час реєстрації типу запису або таксономії.
Створення свого провайдера для Мапи сайту
Але якщо ваш плагін або тема мають якісь свої сутності, які потрібно додати в карту сайту, то для них потрібно буде створити нового провайдера . Це класичний PHP, який розширює абстрактний клас WP_Sitemaps_Provider .
Створений Клас потрібно зареєструвати (підключити) за допомогою функції wp_register_sitemap_provider() :
add_filter( 'init', function(){ $provider = новий Awesome_Plugin_Sitemaps_Provider(); wp_register_sitemap_provider( 'awesome-plugin', $provider ); } );
Цей провайдер буде відповідати за відображення всіх нових Карт сайту, їх пагінацію виведення карток для окремих елементів (посилань).
Приклади створення Провайдерів
#1 Свій провайдер із двома типами та кастомною таблицею
Допустимо у нас у БД є таблиця, в якій зберігаються медіа дані про audio та video сутності. Кожна така сутність має свою сторінку на фронті. Нам потрібно додати всі ці сторінки до Карти сайту.
Створимо свого провайдера, назвемо його megamedia
. Для цього створимо у темі файл class-Megamedia_Sitemaps_Provider.php
із наступним кодом:
class Media_Sitemaps_Provider extends WP_Sitemaps_Provider { // make visibility not protected public $name; /** * Constructor. Sets name, object_type properties. * * $name Provider name. Uses in URL (must be unique). * $object_type The object name that the provider works with. * Passes into the hooks (must be unique). */ public function __construct() { $this->name = 'megamedia'; $this->object_type = 'megamedia'; } /** * Натисніть на list supported object subtypes exposed by the provider. * * @return array List of object subtypes objects keyed by their name. */ public function get_object_subtypes() { return array( 'audio' => new stdClass(), 'video' => new stdClass() ); } /** * Gets a URL list for a sitemap. * * @param int $page_num Page of results. * @param string $subtype Optional. Object subtype name. Default empty. * * @return array Array of URLs для sitemap. */ public function get_url_list( $page_num, $subtype = '' ) { $result = $this->db_query( [ 'subtype' => $subtype, 'paged' => $page_num, ]); $url_list = array(); foreach ($result as $megamedia) { $sitemap_entry = [ 'loc' => home_url( "/megamedia/$subtype/$megamedia->id" ), // 'priority' => 0.5, // 'changefreq' => 'monthly', ]; $url_list[] = $sitemap_entry; } return $url_list; } /** * Gets the max number of pages available for the object type. * * @param string $subtype Optional. Object subtype. Default empty. * @return int Total number of pages. */ public function get_max_num_pages( $subtype = '' ) { $total = $this->db_query( [ 'subtype' => $subtype, 'count' => true, ]); return (int) ceil( $total / wp_sitemaps_get_max_urls( $this->object_type ) ); } /** * Returns the SQL query result. * * @return array Array of query arguments. */ protected function db_query( $args ) { Global $wpdb; $arg = (object) array_merge( [ 'paged' => 1, 'subtype' => 'audio', 'count' => false, ], $ args); $SELECT = $arg->count ? 'count(*)' : '*'; $ WHERE = []; $WHERE[] = 'post_id = 0'; $WHERE[] = $wpdb->prepare( "media_type = %s", $arg->subtype ); $WHERE = implode( 'AND', $WHERE ); $per_page = wp_sitemaps_get_max_urls( $this->object_type ); $offset = ($arg->paged - 1) * $per_page; $LIMIT = sprintf( "LIMIT %d, %d", $offset, $per_page); $sql = "SELECT $SELECT FROM $wpdb->wp_core_data WHERE $WHERE $LIMIT"; $result = $arg->count ? $wpdb->get_var( $sql ) : $wpdb->get_results( $sql ); return $result; } }
Тепер підключимо (зареєструємо) створеного провайдера у файлі functions.php .
add_filter( 'init', 'wpkama_register_sitemap_providers'); function wpkama_register_sitemap_providers(){ require_once __DIR__ .'/class-Megamedia_Sitemaps_Provider.php'; $provider = New Megamedia_Sitemaps_Provider(); wp_register_sitemap_provider($provider->name, $provider); }
Переходимо до Карти сайту і бачимо:
Нотатки:
ВАЖЛИВО: перший параметр функції wp_register_sitemap_provider() повинен бути такий самий як властивість $name у провайдера! І складатися це ім’я може лише із символів a-z
!
Властивості класу WP_Sitemaps_Provider :
- $this->name
- Ім’я провайдера Використовується в URL-картки сайту. Має бути унікальним.
ВАЖЛИВО! Дозволяються лише символи
a-z
. Тобто. не можна використовувати тире, прогалини та малі. Неправильно:similar_posts
,similar-posts
,Similar
. Правильноsimilarposts
. - $this->object_type
- Ім’я об’єкта, з яким працює провайдер (post, term, user). Використовується у хуках. Має бути унікальним.
Методи класу Media_Sitemaps_Provider та WP_Sitemaps_Provider :
- get_object_subtypes()
- Повинен повернути список підтипів, наприклад у постів типи постів. Повертає масив об’єктів, у ключах є імена підтипів.
- get_url_list( $page_num, $subtype = ” )
- Повинний повернути список посилань для кожної картки – список даних для тегів XML <url> . Виглядає цей список як масив масивів, кожен вкладений масив – це кожне посилання. Наприклад:
$url_list = [ [ 'loc'=> 'https://example.com/megamedia/audio/2610735' ], [ 'loc'=> 'https://example.com/megamedia/audio/9514241' ], ... ];
- get_max_num_pages( $subtype = ” )
- Повинен повернути число – загальна кількість елементів для переданого підтипу. Наприклад, для записів WP – це скільки всього записів зазначеного типу запису, наприклад, скільки всього сторінок (page).
- db_query( $args )
- Це довільний свій метод класу, який створює запит у БД і отримує дані за переданими параметрами, зокрема тут враховується підтип та пагінація.
Функції, що використовуються:
- wp_sitemaps_get_max_urls()
-
Зовнішня функція, яка повертає макс. кількість елементів у кожній карті сайту. За промовчанням
2000 .
#2 Провайдер на основі постів
Допустимо ми допрацювали URL постів і тепер, якщо в кінець посилання посту дописати, /similar_posts/
ми потрапляємо на сторінку зі схожими записами. Нам потрібно додати всі такі посилання до Карти сайту.
Назвемо провайдера similarposts
(у назві не можна вказувати прогалини та тире!) і створимо клас провайдера, так:
class Similar_Posts_Sitemaps_Provider extends WP_Sitemaps_Provider { // make visibility not protected public $name; public function __construct() { $this->name = 'similarposts'; $this->object_type = 'similarposts'; } public function get_url_list( $page_num, $subtype = '' ) { $args = $this->wp_query_args(); $args['paged'] = $page_num; $query = new WP_Query( $args ); $url_list = array(); foreach ( $query->posts as $post ) { $sitemap_entry = [ 'loc' => user_trailingslashit( untrailingslashit( get_permalink( $post ) ) .'/similar_posts/' ), ]; $url_list[] = $sitemap_entry; } return $url_list; } public function get_max_num_pages( $subtype = '' ) { $args = $this->wp_query_args(); $args['fields'] = 'ids'; $args['no_found_rows'] = false; $query = new WP_Query( $args ); return $query->max_num_pages; } protected function wp_query_args(){ return array( 'orderby' => 'ID', 'order' => 'ASC', 'post_type' => 'post', 'posts_per_page' => wp_sitemaps_get_max_urls( $this->object_type ), 'post_status' => array( 'publish' ), 'no_found_rows' => true, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, ); } }
Тепер зареєструємо його:
add_filter( 'init', 'wpkama_register_sitemap_providers'); function wpkama_register_sitemap_providers(){ require_once __DIR__ .'/class-Similar_Posts_Sitemaps_Provider.php'; $provider = New Similar_Posts_Sitemaps_Provider(); wp_register_sitemap_provider($provider->name, $provider); }
Готово! Ідемо до карти сайту:
#3 Приклади з ядра
З коробки WP є три провайдера (постачальника) карт сайтів для різних типів. Їхній код можна взяти за основу для створення свого провайдера.
posts
– WP_Sitemaps_Posts {}taxonomies
– WP_Sitemaps_Taxonomies{}users
– WP_Sitemaps_Users {}