XML карта сайта в WordPress

Решил поделится опытом как создать карту сайта в WordPress. В сети можно найти множество плагинов, которые создают файл sitemap.xml в корневой директории WordPress. Главный их недостаток заключается в том, что большинство из них слишком тяжелые, с чрезмерно раздутым функционалом и кривым интерфейсом. Мне не понятно почему разработчики до сих пор не реализовали эту функцию как штатный функционал WordPress.

После нескольких часов поиска, я так и не смог найти подходящий WordPress плагин для создания xml карты сайта. Среди моих требований были лаконичность, простота кода, продуманный интерфейс, без рекламы и выпрашивания денег.

Что касается интерфейса для управления плагином из админки WordPress. Я не вижу в нем никакой необходимости. Независимо от тех параметров, которые мы указали в xml карте сайта, поисковые роботы основе своих алгоритмов будут самостоятельно определять частоту индексации сайта. Логичнее один раз указать эти параметры внутри кода и больше никогда про них не вспоминать.

В итоге для реализации xml карты сайта в WordPress пришлось написать свой небольшой плагин. Признаюсь, в процессе решил не заморачиваться и просто позаимствовал часть кода у одного из плагинов. Чтобы лишний раз не нагружать сервер, можно кэшировать запросы к sitemap.xml в nginx. При желании плагин легко можно допилить под свои потребности.

<?php
/*
Plugin Name: Tiny XML Sitemap
Description: XML Sitemap for Google, Yandex and Yahoo
*/

add_action( 'template_redirect', 'google_sitemap' );

function google_sitemap() {
  if ( ! preg_match( '/sitemap\.xml$/', $_SERVER['REQUEST_URI'] ) ) {
    return;
  }
  global $wpdb;
  $posts = $wpdb->get_results( "SELECT ID, post_title, post_modified_gmt
    FROM $wpdb->posts
    WHERE post_status = 'publish'
    AND post_password = ''
    ORDER BY post_type DESC, post_modified DESC
    LIMIT 50000" );
  header( "HTTP/1.1 200 OK" );
  header( 'X-Robots-Tag: noindex, follow', true );
  header( 'Content-Type: text/xml' );
  echo '' . "\n";
  echo '' . "\n";
  $xml  = '' . "\n";
  $xml .= "\t" . "\n";
  $xml .= "\t\t" . home_url( '/' ) . "\n";
  $xml .= "\t\t" . mysql2date( 'Y-m-d\TH:i:s+00:00', get_lastpostmodified( 'GMT' ), false ) . "\n";
  $xml .= "\t\t" . 'hourly' . "\n";
  $xml .= "\t\t" . '1' . "\n";
  $xml .= "\t" . "\n";

foreach ( $posts as $post ) {
    if ( $post->ID == get_option( 'page_on_front' ) )
      continue;
    if ( ! empty( $post->post_title ) ) {
      $xml .= "\t\n";
      $xml .= "\t\t" . get_permalink( $post->ID ) . "\n";
      $xml .= "\t\t" . mysql2date( 'Y-m-d\TH:i:s+00:00', $post->post_modified_gmt, false ) . "\n";
      $xml .= "\t\t" . 'weekly' . "\n";
      $xml .= "\t\t" . '0.8' . "\n";
      $xml .= "\t\n";
    }
  }
  $xml .= '';
  echo ( "$xml" );
  exit();
}