WordPressをMVC風につかう
WordPressは洗練された管理画面や豊富なテーマファイル、プラグインが存在することから、ブログのようなシンプルなものからECなど複雑なWebアプリケーションの開発にまで様々な用途で用いられています。
カテゴリ機能やタグ機能が標準で実装され、パーマリンクの変更も手軽にできる反面、デフォルトのURLパターンを無視したURL構造の実現には少しテクニックが必要です。
システムの設計上、あるいはSEOを意識したURL構造を自由に実現したいときに使えるカスタムルーティングの実装方法をご紹介します。
URLのリライトルール
ユーザー登録やログインに関する機能のURLを、
登録: http://www.example.com/user/register
ログイン: http://www.example.com/user/login
のように/user以下のディレクトリにまとめたいとします。
/*コンストラクタ内に記述*/
add_action( 'init', array( $this, 'manage_user_routes' ) );
/*ここまで*/
public function manage_user_routes() {
add_rewrite_rule( '^user/([^/]+)/?', 'index.php?control_action=$matches[1]', 'top' );
}
まずプラグインのメインファイルのコンストラクタの中でinitアクションをフックしてURLのカスタムルールを定義します。user/以降の文字列を正規表現で取得し、一致した文字列をcontrol_actionというパラメーター名でindex.phpにGETリクエストを送るように設定しています。
第3引数のtopは、このリライトルールを既存のリライトルールよりも高い優先順位とするためのオプションです。
カスタムクエリ変数
次に、control_actionをパブリッククエリ変数として認めるよう以下のコードをコンストラクタに追加します。
/*コンストラクタ内に記述*/
add_filter( 'query_vars', array( $this, 'manage_user_routes_query_vars' ) );
/*ここまで*/
public function manage_user_routes_query_vars( $query_vars ) {
$query_vars[] = 'control_action';
return $query_vars;
}
control_actionという新しいカスタムクエリ変数を追加して書き換えた配列を返します。
また、URLのリライトルールに変更を加えたためフラッシュしてWordPressに再認識させるための関数も実装します
/*コンストラクタ内に記述*/
register_activation_hook( __FILE__, array( $this, 'flush_application_rewrite_rules' ) );
/*ここまで*/
public function flush_application_rewrite_rules() {
$this->manage_user_routes();
flush_rewrite_rules();
}
カスタムURLに応じたテンプレートを描画
MVCモデルでのコントローラーに当たる部分を下記のように実装します。
/*コンストラクタ内に記述*/
add_action( 'template_redirect', array( $this, 'front_controller' ) );
/*ここまで*/
/*プラグインの接頭辞をhogeとしています*/
public function front_controller() {
global $wp_query;
$control_action = isset ( $wp_query->query_vars['control_action'] ) ? $wp_query->query_vars['control_action'] : '';
switch ( $control_action ) {
case 'register':
do_action( 'hoge_register_user' );
break;
case 'login':
do_action( 'hoge_login_user' );
break;
}
}
WordPressがテンプレートファイルを探すプロセスに割り込むために、"template_redirect"というアクションフックが提供されています。
これをフックしてcontrol_actionというパラメーターが存在する場合は、パラメーターに応じたアクションフックを作成するようにします。
あとは以下のようにアクションフックごとに該当のテンプレートファイルをincludeするような関数を実装して完成です。
/*コンストラクタ内に記述*/
add_action( 'hoge_register_user', array( $this, 'register_user' ) );
/*ここまで*/
public function register_user() {
include dirname(__FILE__) . '/templates/register.php';
}
※ここでdo_actinoを使わずに直接関数を呼び出してしまうと後の機能拡張に弱くなってしまうので、あえてdo_actionを用いてアクションフックを作成し、新機能の追加をしやすいように設計しています。