WordPressでSEOに理想的なディレクトリ構造とパンくずリストを作ってみる
連載:WordPressの理想的なURL構造を目指す

3.WordPressで/カスタムタイプ名/タクソノミー名_親ターム名/子ターム名/個別スラッグ/の形を実現してみる

目標のURL構造

「WordPressでSEO的に理想のパーマリンクを実現してみる」という事ですが、具体的なコードを書く前に、一つお伝えしたいことがあります。
前回の記事では理想のURLは

http://bookof.com/book/technical/pc/web/css/487311232X/
/カスタムタイプ名/親ターム名/子ターム名/孫ターム名/…/個別スラッグ/

としていましたが、本当は違います。
ってか無理…というか厳しい。

その理由は、今回理想のURL構造(ツリー型でディレクトリ構造のまま、URLをアドレスバーから直接操作しても内容のないページは作らない)を目指す為には、カテゴリーやタグ・タクソノミー名を含みたくない。
アーカイブページのタクソノミー名の部分を取りたい
とすると、cssというタグのアーカイブページも作りたくなると問題になってくる
アーカイブページのタクソノミー名の部分を取りたい
というように、リライトルールを適応しようとしても、タグなのかカテゴリーなのか、他のタクソノミーなのかを判断する材料がURLに含まれていないのでどっちを表示していいのか解らない。

ということで、今回目指すURLの中にどうしてもタクソノミー名が必要になってくる。
しかし、URLのツリー構造の中に内容のないページは含まれたくないので、今回の目標は下記のようにする!
GOGLEの推奨する綺麗なディレクトリ構造・URL構造
今回は上記のように、タクソノミー名とターム名をアンダースコアで区切る形にします。

使用テーマのfunction.phpに追記

では具体的なコードを書いてみましょう。
まずずっとご説明してきたとおり、WPに上記の新しいリライトルールを設定します。

使用しているテーマのfunction.php等に下記を追記

function ChangeRewriteRules($mypost, $myterm, $parents) {
	$newrules = array();
	if ( $myterm->parent == 0 ) {  //親タームがなかったら
		if (empty($parents)) {
			$newrules['archive'][$mypost . '/' . $myterm->taxonomy . '_(' . $myterm->slug . ')/?$'] = 'index.php?' . $myterm->taxonomy . '=$matches[1]';  //アーカイブページ用
			$newrules['archive'][$mypost . '/' . $myterm->taxonomy . '_(' . $myterm->slug . ')/page/([0-9]+)/?$'] = 'index.php?' . $myterm->taxonomy . '=$matches[1]&paged=$matches[2]';   //2ページ以降用
			$newrules['single'][$mypost . '/' . $myterm->taxonomy . '_' . $myterm->slug . '/([^/]+)/?$'] = 'index.php?' . $mypost . '=$matches[1]';
		} else {  //親があるターム用
			$newrules['single'][$mypost . '/' . $myterm->taxonomy . '_' . $myterm->slug . '/' . implode('/', $parents) . '/([^/]+)/?$'] = 'index.php?' . $mypost . '=$matches[1]';  //singleページ用
			$parents[count($parents)-1] = '(' . $parents[count($parents)-1] . ')/';
			$newrules['archive'][$mypost . '/' . $myterm->taxonomy . '_' . $myterm->slug . '/' . implode('/', $parents) . '?$'] = 'index.php?' . $myterm->taxonomy . '=$matches[1]';  //アーカイブページ用
			$newrules['archive'][$mypost . '/' . $myterm->taxonomy . '_' . $myterm->slug . '/' . implode('/', $parents) . 'page/([0-9]+)/?$'] = 'index.php?' . $myterm->taxonomy . '=$matches[1]&paged=$matches[2]';  //2ページ以降用
		}
	} else {  //親があったら
		$parentterm = get_term_by('id', $myterm->parent, $myterm->taxonomy);
		array_unshift($parents, $myterm->slug);
		$newrules = ChangeRewriteRules($mypost, $parentterm, $parents);
	}
	return $newrules;
}

function MyRewriteRules($rules) {  //引数:既に設定されているリライトルール
	$newrules = array();	$toriaezu = array();	$single = array();	$archive = array();
	$myposts = get_post_types(array('_builtin' => false));  //全カスタムタイプ取得②
	foreach($myposts as $mypost) {
		$mytaxonomies = get_taxonomies(array('object_type' => array($mypost))); //それのタクソノミー取得③
		foreach ($mytaxonomies as $mytaxonomie) {
			$myterms = get_terms( $mytaxonomie, array('hide_empty' => 0) ); //それのターム取得④
			foreach ($myterms as $myterm) {
				$toriaezu =  ChangeRewriteRules($mypost, $myterm, array()); //リライトルール配列を生成
				$single += $toriaezu['single'];  //順番調整⑤
				$archive += $toriaezu['archive'];
			}
		}
	}
	return $archive + $single + $rules;  //新しいルールを追加して返す⑥
}
add_filter('rewrite_rules_array','MyRewriteRules');

上記を簡単に説明すると、①のadd_filterで、rewrite_rules_arrayというフィルターフックに引っ掛ける。
rewrite_rules_arrayは引数に既に設定されているリライトールを
$rules[該当するルール] = “本当の姿”;
の形で持っているので、ここに新しいルールを追加して返します。

②で全てのカスタムタイプを取得してそれぞれをループ。
ループ内で、カスタムタイプ毎に設定されているタクソノミーを全て取得して、更にループ。
更にそれぞれのタクソノミーに設定されているタームを全て取得して、一つ一つに対して④の処理を実行。

④で
http://bookof.com/book/type_technical/pc/web/css/にアクセスがあったら、
index.php?type=cssの内容を表示しなさい。
http://bookof.com/book/type_technical/pc/web/css/page/2/にアクセスがあったら、
index.php?type=css&paged=2の内容を表示しなさい。
http://bookof.com/book/type_technical/pc/web/css/487311232X/にアクセスがあったら、
index.php?book=487311232Xの内容を表示しなさい。
の形の新しいルールを作成

配列に入っている順番で優先順位が変わるので⑤で調整して、
⑥で、古いルールに新しいルールを足して返す。

これで、新しいカスタムルールの設定は完了いたしました。

Custom Post Type Permalinksを入れる

次に「Custom Post Type Permalinks」プラグインを入れて、カスタム投稿タイプのパーマリンクの設置を変更いたします。
カスタム投稿を作ったら、それに割り当てるタクソノミーが色々あると思います。
今回の場合は
type (本のジャンル)
その他に例えば価格(price)・出版社(publisher)・著者(writer)等が考えられます。
その中から、singleページヘのURLのベースとなるタクソノミーを選びます。

http://bookof.com/book/price_1500-2000/
http://bookof.com/book/publisher_oreilly/
http://bookof.com/book/type_technical/pc/web/css/

今回の場合は、ユーザービリティ等を考えて

本の種類の軸
http://bookof.com/book/type_technical/pc/web/css/487311232X/

を本詳細ページまでのベースのURLとします。

その場合は、カスタム投稿タイプのパーマリンクの設置の
「book」のフィールドに
/type_%type%/%postname%/
と入力して変更を保存
(typeの部分は、詳細ページへの軸となるタクソノミー名に変更して下さい。)
カスタム投稿タイプのパーマリンクの設定

上記でとりあえず理想のURLにアクセスした際に、URLを解決してパラメーターから正しいページの内容を表示できるようになりました。

http://bookof.com/book/type_technical/pc/web/css/
http://bookof.com/book/type_technical/pc/web/css/page/2/
http://bookof.com/book/type_technical/pc/web/css/487311232X/
でアクセスできるようになった!

この形なら、アドレスバーを直接操作しても404ページは含まれずに、本の種類の軸で正しいツリー構造になっている。(pageの事は置いといて下さいっ汗)

これで理想のURLにアクセスして内容を表示できるようになりましたので、今度は「Breadcrumb NavXT」プラグインを使って、このURL構造にぴったしあったパンくずリストを作ってみよう。

連載INDEX

連載:WordPressでSEOに理想的なディレクトリ構造とパンくずリストを作ってみる

WordPressでSEOに理想的なディレクトリ構造とパンくずリストを作ってみる今回はWordPressを使って、Googleが推奨するユーザーにとって理解のしやすいURL構造、検索エンジンがクロールし易いURL構造を目指し、更にそのURL構造に合わせたパンくずリストを作成する事を目標にしています。
GOOGLEさま様になってしまっている昨今、GOOGLEの考えに一喜一憂でございます。
昔は良かったものがペナルティになったり、その逆もあったり、情報も変化していくんですが、とりあえず最近のSEO的な改修作業では基本になるURLの構造をWordPressで作っていこうと思います。

著者