WordPressと静的ページの共存
諸事情によりクライアントワークでWordpressと静的ページを共存させることがありました。
ディレクトリ構造
1 2 3 4 5 6 7 8 |
/ドキュメントルート /assets <- アセットファイル /about <- 静的ファイルのディレクトリ index.html /inc <- 共通パーツ global.html /wp <- Wordpress index.php <- Wordpressの中にあるindex.phpを移動する |
Wordpressはドキュメントルートではなくサブディレクトリに入れ、静的ページとWordpressの両方でドキュメントルート直下のアセットを呼び出します。
また、Wordpressの中に入っているindex.phpをドキュメントルートに移動させます。
wordpressの設定
サイトアドレス (URL)がhttps://xxx.com/の場合WordPress アドレス (URL)はhttps://xxx.com/wp/のように、サブディレクトリまでのアドレスを設定します。
また、サイトトップでWordpressを読み込むように、ドキュメントルートのindex.phpを下記のように変更します。
1 2 |
// require( dirname( __FILE__ ) . '/wp-blog-header.php' ); require( dirname( __FILE__ ) . '/wp/wp-blog-header.php' ); |
これで、サイトトップに訪れた際には、Wordpressで設定しているトップページが表示されます。
共通パーツを呼び出す
グロナビなどをWordpress、静的ページに共通で呼び出したいと思います。
まずは、.htaccessでHTML内でPHPを使えるようにします。書き方はサーバーによっていろいろあるみたいなので、サーバーにあったものを使ってください。
そうすることで、下記のようにインクルード用のファイルを呼び出せるようになります。
1 |
<?php require($_SERVER['DOCUMENT_ROOT'] . '/inc/global.html'); ?> |
ちなみに、.htmlを使っているのはSSIを検討した名残なのでもちろん.phpを使ってもいいと思います。
HTMLファイルでWP関数を使う
Wordpressの独自関数は、当然Wordpressの関数が定義されているファイルを読み込まないと使えません。
下記のようにwp-load.phpを読み込めば静的ページでもWordpressの独自関数を使えるようになります。
1 |
<?php require($_SERVER['DOCUMENT_ROOT'].'/wp/wp-load.php'); ?> |
特定のページだけなら固定ページがありますし、単純なループだけならAPIを使った方がいいと思うのですが、どうしてもWP関数が必要なときにはこういう手段もあります。
sitemap.xml
ここまで紹介したように、Wordpressと静的ページを共存させること自体はそんなに難しくはないかと思います。
これまでsitemap.xmlファイルの出力についてはWordpress単体だとプラグイン任せであることが多かったのですが、プラグインだと静的ページを含めてくれないためSEO面での課題が残りました。
WPテーマ内のfunctions.phpにて動的にsitemap.xmlを出力するようにする必要があります。
SEOの話をしているので、今回はすべてのページがリンクされているページまたはパーツがあるという前提で進めます。それをfile_get_contents()で呼び出してしまおうという、単純なものです。
おすすめは、リンクしたいすべてのページをJSONで集約することです。それをフッターまたはサイトマップページで呼び出し、また、sitemap.xmlを作成するための処理でも呼び出すといいかと思います。
JSONを使わずにべた書きしたHTMLをfile_get_contents()でもいいですが、その場合はpreg_match_all()を使ってhref属性の中身を取り出していくなど追加処理が必要です。
前提が長くなりましたが、コード例は下記のようになります。
1 2 3 4 5 6 7 8 9 |
[ { "title": "サイトについて", "url": "/about/", },{ "title": "ニュース一覧", "url": "/news/" } ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
function sitemap_xml() { date_default_timezone_set('Asia/Tokyo'); $sitemap = '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; $sitemap .= '<lastmod>'.mysql2date("Y-m-d", get_lastpostmodified(), false).'</lastmod><url><loc>' .esc_url(home_url('/')). '</loc><lastmod>'.mysql2date("Y-m-d", get_lastpostmodified(), false).'</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url>'; // サイトトップを最初に入れる $sitemaplist = array(); // すべてのリンクを入れる配列を用意 $url = $_SERVER['DOCUMENT_ROOT'] . '/inc/sitemap.json'; $json = file_get_contents($url); $sitemapArray = json_decode($json, true); foreach ($sitemapArray as $val) { $sitemaplist[] = get_home_url() . $val['url']; // JSONから取り出したURLを配列に入れていく } // すべてのニュース記事を取得して配列に入れる $args = array( 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'modified', 'order' => 'DESC', ); $the_query = new WP_Query( $args ); while ( $the_query->have_posts() ) : $the_query->the_post(); $sitemaplist[] = get_the_permalink(); endwhile; wp_reset_postdata(); // カテゴリーのアーカイブページ $categories = get_categories(); foreach($categories as $category) { $sitemaplist[] = get_category_link($category->term_id); } // タグのアーカイブページ $tags = get_tags(); foreach($tags as $tag) { $sitemaplist[] = get_tag_link($tag->term_id); } $sitemaplist = array_unique($sitemaplist); // 配列内の重複を削除 foreach ($sitemaplist as $item) { $sitemap .= '<url><loc>' .$item. '</loc><changefreq>weekly</changefreq></url>' . "\n"; } $sitemap .= '</urlset>' . "\n"; $fp = fopen( ABSPATH. "sitemap.xml", 'w' ); if ($fp) { fwrite($fp, $sitemap); fclose($fp); } } // 記事を保存したらsitemap.xmlファイルを作り直す add_action( "save_post", "sitemap_xml" ); |
JSONを取得し、ニュース記事など、動的に追加するページを取得。
念のため、配列内の重複を削除し、/wp/sitemap.xmlを出力します。
アーカイブページが無限スクロールのサイトならこれでもいいですが、ページャーを使っていたらアーカイブの2ページ以降のリンクを入れることも必要です。その際はWP_Queryの$found_postsを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// すべてのニュース記事を取得して配列に入れる $args = array( 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'modified', 'order' => 'DESC', ); $the_query = new WP_Query( $args ); while ( $the_query->have_posts() ) : $the_query->the_post(); $sitemaplist[] = get_the_permalink(); endwhile; $max = ceil($the_query->found_posts / 10); // 1ページに10記事表示している場合 for ($i=2; $i < $max + 1; $i++) { $sitemaplist[] = get_home_url() .'/news/page/'.$i.'/'; } wp_reset_postdata(); |
まぁ、こうして書いてますが、私はべた書きHTMLからリンクを拾うはめになったのですがね。
こうすればよかったなーというまとめになります。