WordPress、テンプレートを使用せずにサイトマップを出力する

検索エンジンにサイトを見つけてもらうためにsitemap.xmlを出力するのに、WordpressにはGoogle XML Sitemapsという便利なプラグインがありますが、投稿の量が肥大化して表に出したいものとそうでないものが混在していくとプラグインでは対応しづらくなってくると思います。

そこで、今回はプラグインに頼らずに自分でfeedからsitemap.xmlを出力する方法をまとめていきたいと思います!

親サイトマップと子サイトマップ

sitemap.xml自体にはファイルサイズに制限があるので、出力したいurlが多くなるとこの制約に引っかかってしまいます。

そこでsitema.xmlを親サイトマップとし、その中に検索エンジンに登録したいurlの情報本体を格納した子サイトマップのリンクを格納していきます。

親サイトマップの記述

適当なファイル、今回はfeed-sitemap.phpに親サイトマップを出力する処理を書いていきます

header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true); //xmlで出力する設定
displayFeed(); // xml出力
function displayFeed(){
    $sitemap_children = array("misc.xml","category.xml"); //子サイトマップのファイル名
    $post = get_posts($args_modified)[0];
    $postdate = explode(" ", $post->post_modified);
    $sitemap = '<?xml version="1.0" encoding="UTF-8"?>'."\n"; //必須
    $sitemap .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'."\n"; //必須
    foreach($sitemap_children as $sitemap_child){
        $sitemap .= "\t".'<sitemap>'."\n";
        $sitemap .= "\t"."\t".'<loc>'. home_url()."/".$sitemap_child .'</loc>'."\n";
        $sitemap .= "\t"."\t".'<lastmod>'. "YY-mm-dd".'</lastmod>'."\n"; //更新した日付
        $sitemap .= "\t".'</sitemap>'."\n";
    }
    $sitemap .= '</sitemapindex>'."\n";
    echo $sitemap;
}

このfeed-sitemap.phpを出力した結果は下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <sitemap>
        <loc>http://example.com/misc.xml</loc>
        <lastmod>2018-09-13</lastmod>
    </sitemap>
    <sitemap>
        <loc>http://example.com/category.xml</loc>
        <lastmod>2018-09-13</lastmod>
    </sitemap>
</sitemapindex>

検索エンジンにsitemap.xmlを拾ってもらえるようにhttp://example.com/sitemap.xmlを叩いたときにfeed-sitemap.phpが追加されるようにfuctions.phpなどに以下のように登録しておきましょう。

add_action('do_feed_sitemap', array($this, 'doFeedSitemap'));
add_rewrite_rule('sitemap.xml', 'index.php?feed=sitemap', 'top');

public function doFeedSitemap() {
    load_template( get_template_directory() . '/feeds/feed-sitemap.php');
}

子サイトマップの記述

親サイトマップ同様に子サイトマップとして先程登録したmisc.xmlとcategory.xmlを出力するfeedを用意しましょう。misc.xmlにはトップページのサイト内のURL、category.xmlにはカテゴリーページのURLを出力していきます。

header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true);
displayFeed();
function displayFeed(){
  $contents = array("home1", "home2"); //存在しているトップページ

  $sitemap = '<?xml version="1.0" encoding="UTF-8"?>'."\n"; //必須
  $sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'."\n"; //必須
  foreach($contents as $content){
    $sitemap .= "\t".'<url>'."\n".
    "\t"."\t".'<loc>'.home_url()."/". $content .'</loc>'."\n".
    "\t".'</url>'."\n" ."\n";
  }
  $sitemap .= '</urlset>';
  echo $sitemap;
}

出力はこんな感じです。

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

子サイトマップも同様にURLを登録していきましょう。

add_action('do_feed_misc', array($this, 'doFeedMisc'));
add_rewrite_rule('misc.xml', 'index.php?feed=misc', 'top');

public function doFeedMisc() {
    load_template( get_template_directory() . '/feeds/feed-misc.php');
}

category.xmlについては省略しますがアーギュメントを適切に指定してあげてget_posts関数を実行、post_IDからget_the_permalink関数を実行することで意図した投稿のURLを取得、登録することができるとおもいます!