こんにちは。澤井です! 私はカルテット入社前に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=も加えています。

上記のpcategory-namepageなどを、パブリッククエリとよびます。 パブリッククエリは、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/1https://example.com?p=1&category-name=category-sample&page=へ変換するルールをリライトルールとよびます。

リライトルールは、wp_options.option_namerewrite_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_varsUglyパーマリンクと同じものになります。

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で投稿が表示されないといった問題が発生した場合は、一度リライトルールを確認すると良いかもしれません。