WordPressのプラグインで任意のURLのページを追加する

WordPressのプラグインを作る際に、任意のURLでページを追加したい時がある。

たとえば。

  • テーマに関係なくカスタムなスタイルシートを適用したい。
  • ショッピングカートなど独自の機能をもった動的なページを作りたい。

など。

あと、AJAXアプリケーションをWordPressに実装する場合も、この手を使用する場合が多い。

この方法のメリット

  • まったく独自の機能を持ったページでも、WordPressの初期設定や各種の関数にアクセスできる。
  • WordPressのパーマリンク設定やディレクトリ構造などに依存しない。
  • URLに/wp-content/pluginsとか/wp-content/themesとかが入らない。

WordPressには、update_option()とかget_option()などの便利な関数や、MySQLでプリペアードなSQLを記述するためのクラスが組み込まれており、これらの関数を利用出来ることはとてもメリットが大きい。

任意のURLのページを作成するには?

WordPressに任意のURLを作成するには、$wp_rewriteというグローバル変数に正規表現のURLのパターンなどを定義する必要がある。

あと、いくつかのアクションフックの定義も必要で、これらの処理は結構めんどくさい。

AddRewriteRulesクラス

とうわけで、AddRewriteRulesクラスというのを作成した。

これは上述した処理をシンプルに実装するためのクラスで、以下のような比較的簡単なソースで独自のURLでページを出力することができる。

以下のソースをプラグインとして適用すると、/mystyle.cssにアクセスした際にCSSが表示される。

new AddRewriteRules(
    'mystyle.css$',
    'mystyle',
    'callback_function'
);

function callback_function()
{
  header('Content-type: text/css; charset=UTF-8');
  echo 'body {background-color: #ff0000}';
  exit;
}

使用方法

AddRewriteRulesクラスには、以下のパラメータを定義する。

  1. Rewriteルールに定義するURLの正規表現
  2. WordPressに内部的に渡されるクエリー文字列
  3. そのURLでアクセスがあった際に実行されるコールバック関数

ソース

以下のソースを任意のファイル名で保存して、requireしてください。

<?php

class AddRewriteRules{

    private $rule     = null;
    private $query    = null;
    private $callback = null;

    function __construct($rule, $query, $callback){
        $this->rule     = $rule;
        $this->query    = $query;
        $this->callback = $callback;
        add_filter('query_vars', array(&$this, 'query_vars'));
        add_filter('rewrite_rules_array', array(&$this, 'rewrite_rules_array'));
        add_action('init', array(&$this, 'init'));
        add_action('wp', array(&$this, 'wp'));
    }

    public function init()
    {
        global $wp_rewrite;
        $rules = $wp_rewrite->wp_rewrite_rules();
        if (!isset($rules[$this->rule])) {
            $wp_rewrite->flush_rules();
        }
    }

    public function rewrite_rules_array($rules)
    {
        global $wp_rewrite;
        $new_rules[$this->rule] = $wp_rewrite->index . '?'.$this->query.'=1';
        $rules = array_merge($new_rules, $rules);
        return $rules;
    }

    public function query_vars($vars)
    {
        $vars[] = $this->query;
        return $vars;
    }

    public function wp()
    {
        if (get_query_var($this->query)) {
            call_user_func($this->callback);
        }
    }
}

?>