こんにちは。澤井です! 私はカルテット入社前にWordPressを使ったサイト制作をしていました。 入社後の現在でも保守や構築を作業する事があり、WordPressは私にとってなじみの深いCMSです。
今回は、そんな私にとってなじみの深いWordPressの基本機能である、パーマリンクについてすこし詳しく書こうと思います。
パーマリンク
WordPressの公式ドキュメントでは、パーマリンクを以下のように解説しています。
パーマリンクとは、ブログの個々の投稿、カテゴリーなどの投稿一覧ページへの恒久的 (半永久的) な URL です。
主に使われるパーマリンクは2種類あります。
- Uglyパーマリンク(デフォルト)
- Prettyパーマリンク
パーマリンクは、WordPress管理画面 > 設定 > パーマリンク設定で設定します。

本記事では、Uglyパーマリンクの表示の流れを確認して、その後にPrettyパーマリンクをUglyパーマリンクに変換するルール(リライトルール)についてみていきたいと思います。
Uglyパーマリンク
WordPressをインストールした直後のURL構造は、https://example.com/?p=123のように、クエリ文字列を使用します。
この形式は、Uglyパーマリンクと呼びます。
WordPressは、クエリ文字列にマッチする投稿を表示します。
例えば、スラッグがcategory-sampleのカテゴリーの中で、投稿IDが1の投稿を表示するURLは以下のようになります。
https://example.com?p=1&category-name=category-sample&page=
※ 実際には、https://example.com?p=1で同じ投稿を表示できますが、
説明を分かりやすくするために、category-name=category-sample&page=も加えています。
上記のp、category-name、pageなどを、パブリッククエリとよびます。
パブリッククエリは、WordPressがデータベースに問い合わせする際の条件として使われます。
WordPressで使用可能なパブリッククエリは、WPクラス(wp-includes/class-wp.php)で定義されています。
WordPressは、パブリッククエリをもとに問い合わせ条件を作成し、SQLを実行してデータベースから表示すべき投稿を取得します。
https://example.com?p=1&category-name=category-sample&page=の投稿取得条件は、以下のようになります(投稿取得条件は、WP_Query::query_varsプロパティで確認できます)。
Array
(
[p] => 1
[page] =>
[category_name] => category-sample
)
pageクエリは、今回の記事では重要でないので、説明しませんが、詳しく知りたい方は以下を参考にしてください。
注: ‘page’ クエリ変数には、コンテンツに クイックタグが含まれページ送りが設定されている個別投稿または固定ページのページ数が含まれます。
関数リファレンス/get query var - WordPress Codex 日本語版
Prettyパーマリンク
Prettyパーマリンクは、ユーザーフレンドリーで見た目の良いリンク構造を提供します。
実際の運用では、Uglyパーマリンクを使うことは少なく、Prettyパーマリンクを使用することが多いと思います。
以下、本記事の主題であるPrettyパーマリンクからUglyパーマリンクへ変換するリライトルールについて記載します。
今回は、Prettyパーマリンクを以下のように設定してみます。
カスタム構造 https://example.com/%category%/%post_id%
上記のようにパーマリンクを設定をした場合、https://example.com?p=1&category-name=category-sample&page=で表示される投稿は、以下URLで取得できるようになります。
https://example.com/category-sample/1
WP_Query::query_varsを確認すると、投稿取得条件は、 Uglyパーマリンクと同じになっています。
Array
(
[p] => 1
[page] =>
[category_name] => category-sample
)
https://example.com/category-sample/1をhttps://example.com?p=1&category-name=category-sample&page=へ変換するルールをリライトルールとよびます。
リライトルールは、wp_options.option_nameのrewrite_rulesレコードに格納されています。
WordPressは初期化時に、WP_Rewrite::rulesプロパティにリライトルールを保持します。
(WP_Rewriteオブジェクトはグローバル変数$wp_rewriteとしてアクセスできます)。
パーマリンク構造を、https://example.com/%category%/%post_id%に設定したときのWP_Rewrite::rulesプロパティを確認してみます。
WP_Rewrite::rulesは、正規表現とマッチ後の置き換え方法を表します。
正規表現でキャプチャされた部分を$match配列に順番に適用していきます。 上から順にマッチを試み、最初にマッチしたものを変換ルールとして採用します。
WP_Rewrite Object
(
[permalink_structure] => /%category%/%post_id%
// ...
[rules] => Array
(
[^wp-json/?$] => index.php?rest_route=/
// ...
[(.+?)/([0-9]+)(?:/([0-9]+))?/?$]
=> index.php?category_name=$matches[1]&p=$matches[2]&page=$matches[3] --- (1)
// ...
[(.+?)/?$] => index.php?category_name=$matches[1]
)
// ...
)
https://example.com/category-sample/1は、上記(1)にマッチします。
- 1番目にキャプチャされた
category-sampleは、$matches[1]で使用されて、category_name=category-sampleになる - 2番目にキャプチャされた
1は、$matches[2]で使用されて、p=1になる - 3番目のキャプチャはないので、
$matches[3]は空になり、page=になる
リライトルールが適用された結果、Uglyパーマリンクhttps://example.com?p=1&category-name=category-sample&page=と同じクエリ文字になります。
結果、WP_Query::query_varsもUglyパーマリンクと同じものになります。
Array
(
[p] => 1
[page] =>
[category_name] => category-sample
)
以上、PrettyパーマリンクからUglyパーマリンクへのリライトルールを見てきました。
注:WordPressはフロントコントローラーindex.phpですべてのリクエストを処理するので、他のページにアクセスした時にindex.phpに処理を移すようWebサーバーを設定しておく必要があります。Webサーバーの設定もリライトと呼ばれますが、WordPressのリライト(Ugly/Pretty)とは全く別の設定箇所になりますのでご注意ください。例えばApacheではmod_rewriteを有効にし.htaccessに設定を記述します。
WordPressは、パーマリンクの設定次第でURL構造が大きく変わります。 思ったとおりのURLで投稿が表示されないといった問題が発生した場合は、一度リライトルールを確認すると良いかもしれません。