レンタルサーバー選びの迷いを解決!全力サポートします

Google or AdMax Promotion (srv)

WordPressに独自リライトルールと独自URLパラメータの追加($wp_rewrite/$wp_query)

WordPressは内部的に常にURLのリライトを行いながら、
サイトのトップに配置している「index.php」が処理をしている事はご存知の事と思います。
WordPressの中のコンテンツで独自のURLを認識させるためには、
リライトルールを定義する必要があります。

尚、本ページは以下の1コンテンツとして紹介しているものです。
一連の流れは以下をご参照ください。

どのようなURLを何に置換(リライト)するか?まず考える

最初はどのURLへのアクセスがあったら、
どのようにリライト(URLの内部置換)を行って処理をさせるのか?を考えます。

以下は作例(デモ)です。

今回の作例では「https://rensrv.com/weekday/」というURLのページを起点とします。
そのまま表示すると、現在日付を元に計算した曜日が表示されます。

このURLにはプログラムがショートコードで仕込んであり、
URLの後ろに「YYYY/MM/DD」形式の日付を付けてアクセスすると、
日付に応じた曜日が表示される仕組みです。

結果「2018/01/01」の曜日を判定して「月曜日」が画面に表示されます。
※実際はメッセージ形式で表示しています。

 

この場合「weekday/」に続くURL「YYYY/MM/DD/」を受け取って、
自分自身のURLへ「https://rensrv.com/weekday/」値として受け渡す必要があります。
※すべて「https://rensrv.com/weekday/?ymd=2018/01/01」風に、
…weekday/ の固定ページが処理を受け持っているという事です。

このプログラムを例にして、

サブディレクトリ形式で1つの固定ページや投稿の表示内容を、
アクセスされたURLに応じて切り替える仕組みをご紹介します。

ずっとやりたかったのですが(5年前から)
「やってるよ!」という記事をほとんど見かけませんでした。

たぶん、だけど、これは教えたくないし、教えるのも面倒なのかなと思ったりします。
実際、面倒ですし。

ただURLのパラメータで表示される結果がユニーク(一意性)であり、
個々にそれだけの価値があるコンテンツになるのであれば、
1コンテンツ(ページ)が一気に100にも1万にも・・それ以上にも増やせて怖い程の破壊力かと。

そう、インデックス戦争の現代ですから、他者に教えたくないよね。コレは。

 

まずこのリライトルールをここでは定義します。

プロモーション

Google or AdMax Promotion (srvpos)

考えたリライトルールとカスタム変数を追加する

今回、固定ページのURLの後に「YYYY/MM/DD/」がついた場合に、
付加された部分をクエリパラメータとして処理するように定義します。

functions.phpの記述(ここでは子テーマに定義)

「functions.php」でリライトルールを追加する為のphpファイルを読み込ませます。

個人的にはというか一般的にはテーマをカスタマイズするなら、
子テーマ化をしてから、子テーマのfunctions.phpを編集する事をお勧めします。
子テーマにしたからと言ってミスったら真っ白けっけになるのは同じですので、
併せて、バックアップとローカル環境での十分なテストを行ったうえでアップロードしましょう。

また私は「functions.php」に直接ソースを書かずに、
機能ごとに別のファイルを作り、そのファイルをincludeして利用しています。

(参考)子テーマ – WordPress Codex 日本語版

functions_rewrite.phpの記述

読み込んでいるファイルには以下のように定義しています。

「functions_rewrite.php」の前半はこのようになっています。

クエリ変数の追加

フィルターフック「query_vars」をトリガーに、
「add_query_vars_filter」関数を実行し、独自に定義したい変数を追加します。

この例で利用しているのは2行目「$vars[] = "wd_ymd";」部分です。

これによって、WordPressは「wd_ymd」をクエリ文字列として認識するようになります。

 

リライトルールの追加

続いて、別の関数を定義しています。
ここでは実際のリライトルールを定義します。

環境ごとのpage_idの切替例

3行目では、テスト環境か本番環境(rensrv.com)かを判定し、
それぞれのpage_idを切り替えています。
これはWordPress内記事を作成した際によって異なります。(環境依存)

page_idは記事の編集画面のURLからも確認できます。

例)https://rensrv.com/wdps/wp-admin/post.php?post=39198&action=edit

この39198は固定ページ「https://rensrv.com/weekday/」のpage_idです。

リライトルールの定義

次に、どのようにリライトするかの記述をします。(以下2行に分けています)
まず「https://rensrv.com/weekday/」の後に続く
「YYYY/MM/DD」部分を正規表現でマッチさせます。

'weekday/(([0-9]{1,4})/(0?[1-9]|1[0-2])/(0?[1-9]|[12][0-9]|3[01]))/?$'

条件に一致したら、取得済みのpage_idを指定(?page_id='. $wd_demo)し、
その後に正規表現に一致した部分を後方参照にて変数として受け取っています。
※正規表現のカッコ内に該当した文字が「preg_index(1)」に渡されています。

=> 'index.php?page_id='. $wd_demo .'&wd_ymd='.$wp_rewrite->preg_index(1),

 

.htaccessなどで行うリライトやリダイレクトと似ていますが、
この定義はWordPressの内部URLのみに有効なリライトルールです。

また「get_the_ID();」や「$post->ID;」などでは、
このfunction.phpの読み込み段階でまだ表示対象が決定していないので動的に取得するのは困難かと。

 

リライトルールの初期化更新処理

リライトルールを変更する場合にはルールの初期化を行う必要があります。
以下のように「$wp_rewrite->flush_rules();」を呼び出します。

 

リライト処理の挙動(結果)

これで「https://rensrv.com/weekday/2018/05/30/」のようなURLでアクセスされた場合、
内部的には「https://rensrv.com/weekday/」のページに対して、
以下のようにクエリパラメータが渡されたように処理されます。

WordPress自体には、以下のように処理が渡されていますが。

https://rensrv.com/index.php?page_id=39198&wd_ymd=2018/05/30

 

概念としては、以下の様なURLで処理されているイメージになります。

https://rensrv.com/weekday/?wd_ymd=2018/05/30

 

値が受け取れるようになる点では同じです。
というか、この「index.phpに対してリライトする」って気づくまでかなり悩みました。。。

 

フィルターフック処理の呼び出され順の確認(参考)

「functions_rewrite.php」に定義した各関数を呼び出すフックとして、
以下の3行を記載しています。

add_filter('query_vars', 'add_query_vars_filter' );
add_filter('generate_rewrite_rules', 'test_custom_endpoint' );
add_filter('init', 'test_flush_rewrite_rules');

これは記述した順序は問わず、フィルターフックのタイミングで呼び出され実行されます。
処理の実行順序は「Debug Bar Actions and Filters Addon」プラグインを利用すると、
その時に表示しているページのアクションフックの順序が見れます。

公式サイトの代表例を確認するには以下が参考にはなります。

(参考)プラグイン API/アクションフック一覧 – WordPress Codex 日本語版
(参考)プラグイン API/フィルターフック一覧 – WordPress Codex 日本語版

上記のサンプルでは、すべて「add_filter()」でフックしていますが、
正しくは、こう書くべきなのだと思います。(動いちゃいますけど)

add_filter('query_vars', 'add_query_vars_filter' );
add_action('generate_rewrite_rules', 'test_custom_endpoint' );
add_action('init', 'test_flush_rewrite_rules');

 

アクションに関しては「Debug Bar」で確認すると以下の順であることが確認できます。

  • 43. init
  • 55. generate_rewrite_rules

以下が全リストになります。(一例です、表示するページ・プラグインによって異なります)

 

問題は「query_vars」の実行タイミングですが、
Debug Bar」でも確認できる情報が限られています。

Hook Priority Registered callbacks
query_vars 1
  • [class] GoogleSitemapGeneratorLoader :: RegisterQueryVars
10
  • add_query_vars_filter

あまりはっきりせず、モヤモヤするのですが、
公式ヘルプには以下のように書かれています。

カスタムクエリ変数

URL に付け加えるカスタムクエリ変数(例: add_query_arg() を使った “http://example.com/some_page/?my_var=foo” など)を使用するには、それらを WP_Query が扱えるパブリック・クエリ変数に追加する必要があります。パブリック・クエリ変数は WP_Query のインスタンスが作成される際に作られますが、幸運なことに実際に WP_Query の $query_vars プロパティにデータを投入する前には ‘query_vars’ フィルタが通されます。

つまり、新しい独自クエリ変数を WP_Query に含めるには ‘query_vars’ フィルタにフックしてクエリ変数を $vars 配列に追加すればよいのです。フィルタ関数でその配列を返すようにしましょう。以下をご覧ください。

  • WP_Query::get() を参照。
  • グローバル (object$wp_query を使用。

(参考)関数リファレンス/get query var – WordPress Codex 日本語版

 

とすると、実行タイミングは、

「WP_Query のインスタンスが作成される時」かつ「$query_varsへの値投入前」

であるとされている事が分かります。
また「WP_Query」には以下のように書かれています。

説明

WP_Query は wp-includes/class-wp-query.php に定義されているクラスで、WordPress ブログへの複雑な投稿やページのリクエストを取り扱います。 wp-blog-header.php (バージョン 2.0 では WP クラス) が $wp_query オブジェクトに現在のリクエストを定義する情報を与えることで、$wp_query はどのタイプのクエリを扱っているのか (カテゴリーアーカイブ、年月別アーカイブ、フィード、検索など) を確定し、要求された投稿を取り出します。$wp_query はリクエスト上の情報を多く保持していて、後からでも利用することができます。

関数リファレンス/WP Query – WordPress Codex 日本語版

 

という事になりますので値が設定されるのは、

wp-blog-header.php」なので、アクションフックに照らし合わせると、

  • 73. wp_head

 

およその呼ばれ順はこのようになっていると推測できます。

  • 43. init
  • 55. generate_rewrite_rules
  • 73. wp_head(query_vars)

 

①add_filter(‘init‘, ‘test_flush_rewrite_rules’);
②add_filter(‘generate_rewrite_rules‘, ‘test_custom_endpoint’ );
③add_filter(‘query_vars‘, ‘add_query_vars_filter’ );

①リライトルールを初期化
②リライトルールの挿入追記
③カスタムクエリ変数を登録

 

しかし、なんかもっとすんなり処理順序分かる方法ないですかね。
デバッグすればいいんですけども。

 


何だかんだでアプリケーションを準備するリライトとクエリ文字列の追加が完了です。
このクエリ文字列を受け取って、動的にコンテンツを出力するショートコードを作ります。

 

この囲み部には誤りがありました。以下を参照ください。

以下は全く的外れなアプローチでした。訂正いたします。

これは記述した順序は問わず、フィルターフックのタイミングで呼び出され実行されます。
処理の実行順序は「$wp_filter」の配列キーをチェックすると分かります(たぶん)。

ざっくりこんな感じで抜いています。

 

以下はテスト環境(ローカル)で抜いたものですので、
当サイトのものではありませんが、以下のような出力が得られます。

以下の順で出現しています。

 

その為、それぞれは以下の順で呼ばれることが分かります。

add_filter('init', 'test_flush_rewrite_rules');
add_filter('query_vars', 'add_query_vars_filter' );

add_filter('generate_rewrite_rules', 'test_custom_endpoint' );

①リライトルールを初期化
②カスタムクエリ変数を登録
③リライトルールの挿入追記

誤記終わり。

 

誤記失礼いたしました。

何だかんだでアプリケーションを準備するリライトとクエリ文字列の追加が完了です。
このクエリ文字列を受け取って、動的にコンテンツを出力するショートコードを作ります。


AdMax Promotion

公開日:
最終更新日:2018/06/02

コンテンツナビ
すべて展開 | すべて省略

AdMax Promotion

カテゴリ
すべて展開 | すべて省略

QRコードからもこのURLを開けます。