- 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細)
関数リファレンス/WP Rewrite
この文書はApacheのmod_rewriteに親しい人を想定してします。それらについてまったく聞いたことがなければ、SitepointのBeginner's Guide to URL Rewritingを読んでください。〔訳注:日本語では「ネットワーク管理者(の卵)養成講座」にある翻訳がおすすめです〕また、wp-hackersのメーリングリストにあるOttoのリライトルールの階層についての説明も役立つでしょう。
WP_Rewriteの役割
WP_Rewriteはリライトルールを管理するためのWordPressクラスで、これにより素敵なパーマリンク を実現することができます。データベースの値からリライトルールを生成するにはいくつかのメソッドがあります。内部的にはリライトルールを更新するためや、特定の投稿やページ、カテゴリーアーカイブなどのURLを特定するためなどに使われています。これはwp-includes/rewrite.phpに定義されており、グローバル変数の単一インスタンスとして$wp_rewriteがwp-settings.phpで初期化されます。
メソッドとプロパティ
これはWP_Rewriteの公式ドキュメントです。プロパティには直接アクセスせず、グローバル変数$wp_rewriteのメソッドを利用してください。
プロパティ
- $permalink_structure
- データベースにあるパーマリンク構造。パーマリンク設定ページで登録したものであり、%year%、%month%、%post_id%のようなタグを含んでいます。
- $category_base
- カテゴリーアーカイブページのURLに挿入される文字列。デフォルトは'category/'。
- $category_structure
- カテゴリーアーカイブページのURL構造。これは単に$category_baseと'%category%'を足したもの。
- $author_base
- 投稿者アーカイブページに追加される文字列。デフォルトは'author/'。
- $author_structure
- 投稿者アーカイブページのURL構造。これは単に$author_baseと'%author%'を足したもの。
- $feed_base
- フィードページに追加される文字列。デフォルトは'feed/'。
- $feed_structure
- フィードページのURL構造。これは単に$feed_baseと'%feed%'を足したもの。
- $search_base
- 検索ページに追加される文字列。デフォルトは'search/'。
- $search_structure
- 検索ページのURL構造。これは単に$search_baseと'%search%'を足したもの。
- $comments_base
- $feed_structureが最新のコメントを取得するために追加する文字列。デフォルトは'comments'。
- $comments_feed_structure
- 最新コメントフィードのURL構造。これは単に$comments_baseと$feed_baseと'%feed%'を足したもの。
- $date_structure
- 日付アーカイブのURL構造。'%year%/%monthnum%/%day%'、'%day%/%monthnum%/%year%'、'%monthnum%/%day%/%year%'がありえるが、どれも見つからなければデフォルトの'%year%/%monthnum%/%day%'を使う。様々な関数がこのURL構造を制限する:例 get_year_permastruct()は単に'%monthnum%'と'%day%'タグを$date_structureから取り除く。
- $page_structure
- ページのURL構造。'%pagename%'だけ。
- $front
- $permalink_structureすべてのの先頭につける文字列。
- $root
- WordPressをインストールしたルートURL。すべてのURL構造の先頭に追加される。
- $matches
- リライトルールによってリダイレクトされたページから後方参照を行うために内部的に使われる。
- $rules
- リライトルール。rewrite_rules()が呼ばれたときにセットされる。
- $non_wp_rules
- WordPressのindex.phpにリダイレクトされない(したがってWordPressは感知しない)ルールからなる連想配列。多くは
'Pattern' => 'Substitution'
の形を取る(下記参照のこと) - $rewritecode
- パーマリンク構造が利用できるすべてのタグからなる配列。このリストについてはパーマリンクの使用を参照のこと。
- $rewritereplace
- リライトルールの正規表現によってタグがどのように置換されるかを示す。$rewritereplaceの最初の要素は$rewritecodeの最初の正規表現であり、二番目は二番目に対応するという具合である。
- $queryreplace
- リライトルールの対応する位置によってタグがどのように変換されるかを示す。$rewritereplaceと同じ対応を示す。
メソッド
- add_rewrite_tag($tag, $pattern, $query)
- $rewritecode、$rewritereplace、$queryreplace配列に要素を追加する。もし$tagがすでに内に存在する場合、既存の値が上書きされる。
- flush_rules()
- リライトルールを再生成し、データベースに保存する。
- generate_rewrite_rule($permalink_structure, $walk_dirs = false)
- パーマリンク構造から余計な要素を省いたルールを生成する。ページやフィードへのルールは生成されない。
- generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $page = true, $feed = true, $forcomments = false, $walk_dirs = true)
- 与えられた構造$permalink_structureによってリライトルールを生成する巨大な関数です。もし$pageがtrueなら、異なるページ(techカテゴリーアーカイブの2ページ目を示す/category/tech/page/2など)にアクセスするための追加リライトルールが生成されます。もし$feedがtrueなら、現在のページのフィードにアクセスさせないためのリライトルールが生成され、$forcommentsがtrueならばコメントフィードがそうなります。$walk_dirsがtrueならば、URL構造が提供するすべてのディレクトリに対するリライトルールが生成されます(例:'/%year%/%month%/%day/'が与えられたら、'/%year%/', /%year%/%month%/', '/%year%/%month%/%day%/'に対してリライトルールが生成される)。この関数はキーとして正規表現を、値としてを持つ置換結果を持つ連想配列を返します。
- get_date_permastruct(), get_category_permastruct(), get_date_permastruct() etc.
- まだ設定されていないプロパティにデフォルト値を与えます(例:$date_structureに対してget_date_permastruct())。get_month_permastruct()関数とget_year_permastruct()関数は対応するプロパティを持っておらず、$date_structureを取って、詳細なタグを排除します(例:get_month_permastruct()関数は自分よりも詳細な'%day%'タグを削除します)。
- init()
- オブジェクトを設定し、データベースから$permalink_structureと$category_baseを取得し、$rootにはを$indexと'/'を設定します。$frontにはパーマリンクの先頭すべてにタグを追加します。その他のプロパティはすべて削除します。
- mod_rewrite_rules()
- すべてのルールを配列ではなく文字列で返します。すべてがApacheの<IfModule>ブロックでラップされ、mod_rewriteが有効かどうかを確認します。
- page_rewrite_rules()
- 作成したページすべてのルールを返します。
- rewrite_rules()
- generate_rewrite_rules()と同じように$rulesに初期値を設定して連想配列で返します。これは投稿、日付、コメント、検索、カテゴリー、投稿者、ページ構造から生成されます。
- set_category_base($category_base)
- カテゴリーベースを変更します。
- set_permalink_structure($permalink_structure)
- パーマリンク構造を変更します。
- using_index_permalinks()
- Returns true ブログがPATHINFOパーマリンクを使っているかどうかを確かめます。
- using_mod_rewrite_permalinks
- Returns true mod_rewriteを使ったprettyパーマリンクを設定しているかどうかを確かめます。
- using_permalinks()
- Returns true ブログが何らかのパーマリンク構造を使っているかどうかを確認します(例:デフォルトクエリ?p=n,
?cat=nでないかどうか)
- WP_Rewrite (constructor)
- init()を呼び出します。
- wp_rewrite_rules()
- rewrite_rules()でリライトルールの配列を返しますが、mod_rewriteの後方参照の代わりに$matches[xxx]を使います。これは.htaccessに書き出すのではなく、PHP内でリライトルールを扱うときに役立ちます。
プラグインフック
リライトルールはブログ関数にとって重要な機能ですが、WordPressはプラグインがその生成プロセスのいくつかにフックを登録することを許可しています。特にrewrite_rules()はリライトルール生成プロセスに対して9つのフィルターと1つのアクションを提供しています。以下はrewrite_rules()に対して登録できるフィルターです。
- パーマリンクを生成するリライトルールにフィルターをかけるにはpost_rewrite_rulesを使います。
- 日付アーカイブのURLを生成するリライトルールにフィルターをかけるにはdate_rewrite_rulesを使います。
- カテゴリーアーカイブを生成するリライトルールにフィルターをかけるにはcategory_rewrite_rulesを使います。
- 検索URLを生成するリライトルールにフィルターをかけるにはsearch_rewrite_rulesを使います。
- 最新コメントのフィードURLを生成するリライトルールにフィルターをかけるにはcomments_rewrite_rulesを使います。
- 投稿者アーカイブページのURLを生成するリライトルールにフィルターをかけるにはauthor_rewrite_rulesを使います。
- ページを生成するリライトルールにフィルターをかけるにはpage_rewrite_rulesを使います。
- ブログのルートを生成するためのリライトルールにフィルターをかけるにはroot_rewrite_rulesを使います。
- すべてろリライトルールにフィルターをかけるには、rewrite_rules_arrayを使います。
- アクションフックgenerate_rewrite_rulesはすべてのリライトルールが生成されたあとに適用されます。関数がパラメータを持つ場合は$wp_rewriteオブジェクト全体への参照を渡します。
mod_rewrite_rules()関数はrewrite_rules()によって生成される配列を受け取り、.htaccessにリライトルールを設定します。この関数はフィルターも持ち、このフィルターは関数に対して.htaccessに書き込む文字列(<IfModule>ブロックを含む)を渡します。(注:rewrite_rulesフックを使っているプラグインを参照できますが、この非推奨されています)
例
(カスタムクエリを参照のこと) プラグインは$wp_rewriteオブジェクトに対してやりそうなことといえば、独自のリライトルールを追加することです。これはとてもシンプルです。rewrite_rules_arrayフィルタを利用します。
http://mysite/project/1をhttp://mysite/index.php?pagename=project&id=1にリライトする簡単で雑な例をお見せします:
add_filter('rewrite_rules_array','wp_insertMyRewriteRules'); add_filter('query_vars','wp_insertMyRewriteQueryVars'); add_filter('init','flushRules'); // ルールを追加するときはflush_rules()を忘れないように function flushRules(){ global $wp_rewrite; $wp_rewrite->flush_rules(); } // 新しいルールを追加 function wp_insertMyRewriteRules($rules) { $newrules = array(); $newrules['(project)/(\d*)$'] = 'index.php?pagename=$matches[1]&id=$matches[2]'; return $newrules + $rules; } // 変数idを追加して、WordPressが認識できるようにする function wp_insertMyRewriteQueryVars($vars) { array_push($vars, 'id'); return $vars; }
flush_rules関数はとても遅いので、実装するときにはすべてのページで実行されるinitフィルターで呼び出さないようにしてください。そのかわり、この関数はリライトルールが変更されるときにだけ呼び出すようにしてください。プラグインのregister_activation_hookだけで消去すれば十分でしょう。
Jerome's Keywordsプラグインはhttp://example.com/tag/sausagesのようなURLでこれを実現しています。
function keywords_createRewriteRules($rewrite) { global $wp_rewrite; // リライトトークンを追加 $keytag_token = '%tag%'; $wp_rewrite->add_rewrite_tag($keytag_token, '(.+)', 'tag='); $keywords_structure = $wp_rewrite->root . "tag/$keytag_token"; $keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure); return ( $rewrite + $keywords_rewrite ); }
$rewrite配列自体にリライトルールを追加する代わりに、JeromeはWP_Rewriteのgenerate_rewrite_rules()関数を使って二つ目の配列$keywords_rewriteを作成することを選んでいます。 この関数を使うことによって、プラグインは追加ページ(page/2など)やフィードページ(feed/atom)などのためにリライトルールを生成する必要がなくなります。この配列は$rewriteに追加され、新しい配列が返ってきます。
このわかりやすい例はライアン・ボーレンのFeed Directorプラグインです。これはhttp://example.com/feed.xmlのようなURLをhttp://example.com/feed/rss2にリダイレクトします。
function feed_dir_rewrite($wp_rewrite) { $feed_rules = array( 'index.rdf' => 'index.php?feed=rdf', 'index.xml' => 'index.php?feed=rss2', '(.+).xml' => 'index.php?feed=' . $wp_rewrite->preg_index(1) ); $wp_rewrite->rules = $feed_rules + $wp_rewrite->rules; } // フックを登録 add_filter('generate_rewrite_rules', 'feed_dir_rewrite');
ここでは単純な配列なので、generate_rewrite_rules()を呼ぶ必要はありません。WordPressにプラグインのルールが追加されるだけです。注意点としては、この関数generate_rewrite_rulesは引数としてリライトルールそのものではなく、$wp_rewriteオブジェクト全体を参照に持つということです。
もちろん、WordPressがリライトルールを処理する前にリライトルールを追加しているので、あなたのプラグインのリライトルールには、WordPressがもともとリライトルールに対して行うべきだった処理すべてが適用されます。ちょうど、.htaccessファイルに書いたのと同じ効果を持ちます。
WordPress以外のリライトルール
<?php $wp_rewrite->non_wp_rules = array( 'Pattern' => 'Substitution' ); print_r($wp_rewrite->mod_rewrite_rules()); ?>>
出力
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /wp_home/ RewriteRule ^Pattern /wp_home/Substitution [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /wp_home/index.php [L] </IfModule>
/wp_home/はWordPressのホームディレクトリ(またはWordPressがWebルートにインストールされた場合はルートURLである/)