SEO対策のひとつとして、サーチエンジンにサイトストラクチャや構成ページなどを通知するsitemap.xml。
WordPressの最新バージョンではデフォルトでsitemap.xmlが出力されるようになったほか、sitemap.xmlを自動生成するプラグインやテーマも多く存在するため、通常直接sitemap.xmlをカスタマイズすることは少なくなりました。
ここでは、これらのプラグインなどによるsitemap.xmlとは別に、sitemap.xml(のフォーマットのxml)を動的に出力する方法について解説します。
WordPressでsitemap.xmlを自力で出力する方法
WordPressでsitemap.xmlを出力する方法はいくつか考えられますが、大きく「サイトの更新時にファイルを静的に書き出しておく」方法と、「検索エンジンなどがアクセスしたタイミングで動的に内容を出力する」方法などが考えられます。
サイトの更新時にsitemap.xmlファイルを静的に書き出す
投稿や固定ページなどの更新に合わせて自前でsitemap.xmlを出力するサンプルコードです。
<?php
function generate_static_sitemap_xml()
{
$allPosts = get_posts(array(
'numberposts' => -1,
'orderby' => 'modified',
'post_type' => array('post', 'page'),
'order' => 'DESC'
));
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
foreach ($allPosts as $post) {
setup_postdata($post);
$postdate = explode(" ", $post->post_modified);
$xml .= '<url>' .
'<loc>' . get_permalink($post->ID) . '</loc>' .
'<lastmod>' . $postdate[0] . '</lastmod>' .
'<changefreq>monthly</changefreq>' .
'</url>';
}
$xml .= '</urlset>';
$fp = fopen(ABSPATH . "ext-static-sitemap.xml", 'w');
fwrite($fp, $xml);
fclose($fp);
}
add_action("publish_post", array($this, "generate_static_sitemap_xml"));
add_action("publish_page", array($this, "generate_static_sitemap_xml"));
?>
こちらでは、publish_post
、publish_page
のアクションフックを使って、投稿などが公開されるタイミングですべての投稿データを一覧にしたxmlをext-static-sitemap.xml
ファイルに書き込む形で機能を実現します。
generate_static_sitemap_xml
ではすべての投稿と固定ページを取得して、ループですべてを出力するようにしているので、投稿の数が膨大になると書き出しの処理に時間がかかったりなど問題が起きる場合があります。
また、このsitemap.xmlは投稿者がコンテンツを公開した時に更新されるため、動的にURLが生成されるようなサイトの場合、それらのURLを反映させることはできません。
動的にsitemap.xmlを出力する
ユーザーによってページが作られるCGMや、外部のAPIと連携して自動的にページを生成するWebサービスなど、編集者の投稿などとは別のタイミングで動的にURLが発行されるようなカスタマイズがされているような場合、上記の静的なsitemap.xmlの出力ではリアルタイムに検索エンジンにサイト構成の変更を通知させることができません。
また、プラグインやテーマを使った場合でも前述のような自動生成のURLは登録できない(yoast seoなどにはそれっぽいアクションフックがある?)ので、これらの生成されたページを自動的にsitemap.xmlに反映したいような場合、sitemap.xmlの内容を動的に返す必要があります。
以下はsitemap.xmlの内容を動的に返すコードの例です。
<?php
function generate_dynamic_sitemap_xml()
{
$allPosts = get_posts(array(
'numberposts' => -1,
'orderby' => 'modified',
'post_type' => array('post', 'page'),
'order' => 'DESC'
));
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
foreach ($allPosts as $post) {
setup_postdata($post);
$postdate = explode(" ", $post->post_modified);
$xml .= '<url>' .
'<loc>' . get_permalink($post->ID) . '</loc>' .
'<lastmod>' . $postdate[0] . '</lastmod>' .
'<changefreq>monthly</changefreq>' .
'</url>';
}
$xml .= '</urlset>';
header('Content-Type: application/rss+xml; charset=UTF-8');
echo $xml;
}
function init_generate_dynamic_sitemap_xml()
{
add_action('do_feed_ext-sitemap', 'generate_dynamic_sitemap_xml');
add_rewrite_rule('ext-sitemap.xml', 'index.php?feed=ext-sitemap', 'top');
}
add_action('init', 'init_generate_dynamic_sitemap_xml');
?>
こちらの例では、add_rewrite_rule
とdo_feed_*
のアクションフック使って、サイトマップフィードにリアルタイムでアクセスされたときの処理関数を追加しています。
do_feed_*
アクションフックはxmlフィードにアクセスされたときに発生するアクションフックで、do_feed_
に続く文字列でフィード名を指定することができます。
上記の例ではdo_feed_ext-sitemap
と指定しており、これによってhttps://(サイト)/index.php?feed=ext-sitemap
のURLからオリジナルのフィードにアクセスできるようになっています。
また、add_rewrite_rule
はURLのリライトルールを指定するもので、これにより上記のURLに加えてhttps://(サイト)/ext-sitemap.xml
からも同ページにアクセスできるように設定しています。(GoogleサーチコンソールにはURL形式の制限などはないので、SEO上は/index.php?feed=ext-sitemap
のまま登録しても特に問題ありません。)
サンプルコードでは静的な出力方法と同じく投稿と固定ページを出力する例になっていますが、こちらの場合はGoogleクローラーなどのアクセスのタイミングでコードが実行されるため、動的ページのURLや通常の投稿やタクソノミー以外のURLなどを出力して最新のサイト構造を検索エンジンに伝えることも可能です。
サンプルではgenerate_dynamic_sitemap_xml()
関数内で作ったxmlのコードをecho
で出力しています。この中で$xml
の本文を作ることで自由にsitemap.xmlを返すことが可能です。
実際はこのまま動かしてしまうとサーバーの負荷が大きくなってしまうことがあるので、キャッシュ関連の処理も組み合わせると安心ですね。
コメント