WordPressの表示フローは概ね以下のようになります。
パーマリンク生成
設定
> パーマリンク
からリライトルールを設定1
で設定したリライトルールに沿ってprettyパーマリンクを生成投稿表示
WordPressのパーマリンクは大きく2つに分けられます。
Ugly
パーマリンク(例 https://example.com/index.php?p=12345&cat=123)Pretty
パーマリンク”(例:https://example.com/sample/12345)本記事ではPretty
パーマリンクがUgly
パーマリンクに変換されるフローを記載しています。
※ Prettyパーマリンクの構造は基本的に設定
> パーマリンク
から指定します。
※ パーマリンクはDBに格納されていません。↑の設定に応じて動的に作成されます。
wp_options.option_name
のrewrite_rules
(WP_Rewrite::rules
)が決まるアクセス
https://example.com/category-sample/1
)WP_Rewrite::rules
をもとにUglyパーマリンクに変換(例:https://example.com?p=1&category-name=category-sample&page=)Webサイト表示の場合HTTPリクエストを受け取って起動したWordPressは、HTTPリクエストに含まれるクエリ文字列またはURLの一部をWordPressのリクエスト変数として解釈し、WordPressクエリ文字列を実行します。HTTPリクエストに含めることができるクエリ変数をパブリッククエリ変数といいます。
O'Reilly 詳解WordPress プライム・ストラテジー株式会社 p95
パブリック変数はwp-includes/class-wp.php
で定義されている。
<?php
/**
* WordPress environment setup class.
*
* @package WordPress
* @since 2.0.0
*/
class WP {
/**
* Public query variables.
*
* Long list of public query variables.
*
* @since 2.0.0
* @var string[]
*/
public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'favicon', 'taxonomy', 'term', 'cpage', 'post_type', 'embed' );
パブリッククエリをリライトルールに沿って解釈して、問合せを(SQL)発行して投稿を取得する。
アクセス時のパブリッククエリは、WP_Query::query_vars
に格納される
wp-setting.phpの中に、WordPressによるURLの解釈、リライトのために重要な2つのオブジェクト、$wp_queryと$wp_rewriteが初期化されます。
Rewrite APIその1 「Rewriteとパーマリンク」(WordPressプラグイン開発のバイブルのボツ原稿から)
WordPressのリライトルールは、グローバル変数$wp_rewrite
に格納されている。
リライト関連の情報は、wp_options
に格納されている。
以下に代表的なレコードを記載する。
option_name | option_value |
---|---|
permalink_structure | /%category%/%post_id% |
rewrite_rules | マッチ規則の正規表現がシリアライズされて保存 |
rewrite_rules_array
flush_rewrite_rules
flush_rewrite_rule
をコードで呼び出すか、管理画面のパーマリンク画面を開くと自動で反映されるプラグインによるリライトルールの追加時に、WordPressのデータベースにtransientキャッシュとして登録されているリライトルールを変更する処理を加えなければなりません。
Rewrite APIその1 「Rewriteとパーマリンク」(WordPressプラグイン開発のバイブルのボツ原稿から)
WP_Rewrite Object
(
[permalink_structure] => /%postname%/
[use_trailing_slashes] => 1
[author_base] => author
[page_structure] => %pagename%
[search_base] => search
[comments_base] => comments
[pagination_base] => page
[comments_pagination_base] => comment-page
[feed_base] => feed
[comment_feed_structure] => comments/feed/%feed%
[feed_structure] => feed/%feed%
[front] => /
[root] =>
[index] => index.php
[matches] =>
[rules] => Array
(
[^wp-json/?$] => index.php?rest_route=/
[^wp-json/(.*)?] => index.php?rest_route=/$matches[1]
[^index.php/wp-json/?$] => index.php?rest_route=/
[^index.php/wp-json/(.*)?] => index.php?rest_route=/$matches[1]
[category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
[category/(.+?)/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
[category/(.+?)/embed/?$] => index.php?category_name=$matches[1]&embed=true
[category/(.+?)/page/?([0-9]{1,})/?$] => index.php?category_name=$matches[1]&paged=$matches[2]
[category/(.+?)/?$] => index.php?category_name=$matches[1]
[tag/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?tag=$matches[1]&feed=$matches[2]
[tag/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?tag=$matches[1]&feed=$matches[2]
[tag/([^/]+)/embed/?$] => index.php?tag=$matches[1]&embed=true
[tag/([^/]+)/page/?([0-9]{1,})/?$] => index.php?tag=$matches[1]&paged=$matches[2]
[tag/([^/]+)/?$] => index.php?tag=$matches[1]
[type/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?post_format=$matches[1]&feed=$matches[2]
[type/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?post_format=$matches[1]&feed=$matches[2]
[type/([^/]+)/embed/?$] => index.php?post_format=$matches[1]&embed=true
[type/([^/]+)/page/?([0-9]{1,})/?$] => index.php?post_format=$matches[1]&paged=$matches[2]
[type/([^/]+)/?$] => index.php?post_format=$matches[1]
[.*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\.php$] => index.php?feed=old
[.*wp-app\.php(/.*)?$] => index.php?error=403
[.*wp-register.php$] => index.php?register=true
[feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?&feed=$matches[1]
[(feed|rdf|rss|rss2|atom)/?$] => index.php?&feed=$matches[1]
[embed/?$] => index.php?&embed=true
[page/?([0-9]{1,})/?$] => index.php?&paged=$matches[1]
[comments/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?&feed=$matches[1]&withcomments=1
[comments/(feed|rdf|rss|rss2|atom)/?$] => index.php?&feed=$matches[1]&withcomments=1
[comments/embed/?$] => index.php?&embed=true
[search/(.+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?s=$matches[1]&feed=$matches[2]
[search/(.+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?s=$matches[1]&feed=$matches[2]
[search/(.+)/embed/?$] => index.php?s=$matches[1]&embed=true
[search/(.+)/page/?([0-9]{1,})/?$] => index.php?s=$matches[1]&paged=$matches[2]
[search/(.+)/?$] => index.php?s=$matches[1]
[author/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?author_name=$matches[1]&feed=$matches[2]
[author/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?author_name=$matches[1]&feed=$matches[2]
[author/([^/]+)/embed/?$] => index.php?author_name=$matches[1]&embed=true
[author/([^/]+)/page/?([0-9]{1,})/?$] => index.php?author_name=$matches[1]&paged=$matches[2]
[author/([^/]+)/?$] => index.php?author_name=$matches[1]
[([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]
[([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&feed=$matches[4]
[([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/embed/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&embed=true
[([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]
[([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]
[([0-9]{4})/([0-9]{1,2})/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]
[([0-9]{4})/([0-9]{1,2})/(feed|rdf|rss|rss2|atom)/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&feed=$matches[3]
[([0-9]{4})/([0-9]{1,2})/embed/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&embed=true
[([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$] => index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]
[([0-9]{4})/([0-9]{1,2})/?$] => index.php?year=$matches[1]&monthnum=$matches[2]
[([0-9]{4})/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?year=$matches[1]&feed=$matches[2]
[([0-9]{4})/(feed|rdf|rss|rss2|atom)/?$] => index.php?year=$matches[1]&feed=$matches[2]
[([0-9]{4})/embed/?$] => index.php?year=$matches[1]&embed=true
[([0-9]{4})/page/?([0-9]{1,})/?$] => index.php?year=$matches[1]&paged=$matches[2]
[([0-9]{4})/?$] => index.php?year=$matches[1]
[.?.+?/attachment/([^/]+)/?$] => index.php?attachment=$matches[1]
[.?.+?/attachment/([^/]+)/trackback/?$] => index.php?attachment=$matches[1]&tb=1
[.?.+?/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[.?.+?/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[.?.+?/attachment/([^/]+)/comment-page-([0-9]{1,})/?$] => index.php?attachment=$matches[1]&cpage=$matches[2]
[.?.+?/attachment/([^/]+)/embed/?$] => index.php?attachment=$matches[1]&embed=true
[(.?.+?)/embed/?$] => index.php?pagename=$matches[1]&embed=true
[(.?.+?)/trackback/?$] => index.php?pagename=$matches[1]&tb=1
[(.?.+?)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?pagename=$matches[1]&feed=$matches[2]
[(.?.+?)/(feed|rdf|rss|rss2|atom)/?$] => index.php?pagename=$matches[1]&feed=$matches[2]
[(.?.+?)/page/?([0-9]{1,})/?$] => index.php?pagename=$matches[1]&paged=$matches[2]
[(.?.+?)/comment-page-([0-9]{1,})/?$] => index.php?pagename=$matches[1]&cpage=$matches[2]
[(.?.+?)(?:/([0-9]+))?/?$] => index.php?pagename=$matches[1]&page=$matches[2]
[[^/]+/attachment/([^/]+)/?$] => index.php?attachment=$matches[1]
[[^/]+/attachment/([^/]+)/trackback/?$] => index.php?attachment=$matches[1]&tb=1
[[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$] => index.php?attachment=$matches[1]&cpage=$matches[2]
[[^/]+/attachment/([^/]+)/embed/?$] => index.php?attachment=$matches[1]&embed=true
[([^/]+)/embed/?$] => index.php?name=$matches[1]&embed=true
[([^/]+)/trackback/?$] => index.php?name=$matches[1]&tb=1
[([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?name=$matches[1]&feed=$matches[2]
[([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?name=$matches[1]&feed=$matches[2]
[([^/]+)/page/?([0-9]{1,})/?$] => index.php?name=$matches[1]&paged=$matches[2]
[([^/]+)/comment-page-([0-9]{1,})/?$] => index.php?name=$matches[1]&cpage=$matches[2]
[([^/]+)(?:/([0-9]+))?/?$] => index.php?name=$matches[1]&page=$matches[2]
[[^/]+/([^/]+)/?$] => index.php?attachment=$matches[1]
[[^/]+/([^/]+)/trackback/?$] => index.php?attachment=$matches[1]&tb=1
[[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$] => index.php?attachment=$matches[1]&cpage=$matches[2]
[[^/]+/([^/]+)/embed/?$] => index.php?attachment=$matches[1]&embed=true
)
[extra_rules] => Array
(
)
[extra_rules_top] => Array
(
[^wp-json/?$] => index.php?rest_route=/
[^wp-json/(.*)?] => index.php?rest_route=/$matches[1]
[^index.php/wp-json/?$] => index.php?rest_route=/
[^index.php/wp-json/(.*)?] => index.php?rest_route=/$matches[1]
)
[non_wp_rules] => Array
(
)
[extra_permastructs] => Array
(
[category] => Array
(
[with_front] => 1
[ep_mask] => 512
[paged] => 1
[feed] => 1
[forcomments] =>
[walk_dirs] => 1
[endpoints] => 1
[struct] => /category/%category%
)
[post_tag] => Array
(
[with_front] => 1
[ep_mask] => 1024
[paged] => 1
[feed] => 1
[forcomments] =>
[walk_dirs] => 1
[endpoints] => 1
[struct] => /tag/%post_tag%
)
[post_format] => Array
(
[with_front] => 1
[ep_mask] => 0
[paged] => 1
[feed] => 1
[forcomments] =>
[walk_dirs] => 1
[endpoints] => 1
[struct] => /type/%post_format%
)
)
[endpoints] => Array
(
)
[use_verbose_rules] =>
[use_verbose_page_rules] => 1
[rewritecode] => Array
(
[0] => %year%
[1] => %monthnum%
[2] => %day%
[3] => %hour%
[4] => %minute%
[5] => %second%
[6] => %postname%
[7] => %post_id%
[8] => %author%
[9] => %pagename%
[10] => %search%
[11] => %category%
[12] => %post_tag%
[13] => %post_format%
)
[rewritereplace] => Array
(
[0] => ([0-9]{4})
[1] => ([0-9]{1,2})
[2] => ([0-9]{1,2})
[3] => ([0-9]{1,2})
[4] => ([0-9]{1,2})
[5] => ([0-9]{1,2})
[6] => ([^/]+)
[7] => ([0-9]+)
[8] => ([^/]+)
[9] => ([^/]+?)
[10] => (.+)
[11] => (.+?)
[12] => ([^/]+)
[13] => ([^/]+)
)
[queryreplace] => Array
(
[0] => year=
[1] => monthnum=
[2] => day=
[3] => hour=
[4] => minute=
[5] => second=
[6] => name=
[7] => p=
[8] => author_name=
[9] => pagename=
[10] => s=
[11] => category_name=
[12] => tag=
[13] => post_format=
)
[feeds] => Array
(
[0] => feed
[1] => rdf
[2] => rss
[3] => rss2
[4] => atom
)
)
// カスタム投稿タイプmanualのrewriteルールを追加
add_filter( 'rewrite_rules_array', function($rules) {
$new_rules = [
'manual/([0-9]+)/?$' => 'index.php?post_type=manual&p=$matches[1]',
];
return $new_rules + $rules;
});
add_filter( 'pre_post_link', function($permalink, $post, $leavename) {
if ( $post->ID !== $post->post_name ) {
return '/%category%/%postname%';
}
//$permalink をカスタマイズ
return $permalink;
}, 10, 3 );
add_filter( 'rewrite_rules_array', function($rules) {
$new_rules = [
'info/.+/([0-9a-zA-Z-_]+)$' => 'index.php?name=matches[1]',
];
return $rules + $new_rules;
});