WordPressの管理画面でAjaxを実装する方法を、サンプルコードを使って説明します。
管理画面は、Ajaxを使うことがあらかじめ想定されているので、かんたんにAjax通信ができます。
WordPressのAjax
WordPressのAjaxの処理の流れです。
JavaScriptでリクエスト送信。
↓
Ajax通信
↓
PHPプログラムが受信。
↓
PHPプログラムで処理実行、レスポンスを返す。
↓
Ajax通信
↓
JavaScriptでレスポンスを受け取る。
さっそく実装しましょう。
JavaScriptのコーティング
AjaxはJavaScriptのリクエスト送信からはじまります。
WordPressでは
jsファイルのキュー登録
JavaScriptのリクエスト送信処理実装
のふたつです。
jsファイルのキュー登録(PHP)
WordPressではおなじみのjsファイルのキュー登録です。htmlに
<script type='text/javascript' src='**.js'></script>
を出力します。
これに、ajaxの処理を書くjsファイルを登録します。これはPHPコードです。
add_action( 'admin_enqueue_scripts', function() {
$handle = 'my_ajax_handle';
$js_url = plugins_url( 'my-plugins/js/clear-cache.js', __FILE__ );
wp_register_script( $handle, $js_url, [ 'jquery' ], '', true);
$localize = [
'ajax_url' => admin_url( 'admin-ajax.php' ),
'action' => 'clear_cache',
];
wp_localize_script( $handle, 'localize', $localize );
wp_enqueue_script( $handle );
} );
(jsファイルのurlは適宜変更。ここではプラグインファイルを想定。)
テーマやプラグインに追加します。
テーマ | functions.phpなど |
プラグイン | プラグインのホームディレクトリと同名の.phpファイルなど |
サンプルコードは、独自の管理画面をプラグイン化したときを想定しています。
ローカライズ
wp_localize_script()
管理画面で使うAjaxのリクエスト送信先URLは、必ず
//(host)/wp-admin/admin-ajax.php
でないといけません。このパスをローカライズのオブジェクト変数にセットします。ついでにaction文字列も。
$localize = [
'ajax_url' => admin_url('admin-ajax.php'),
'action' => 'clear_cache',
];
ローカライズは、JavaScriptでPHPの翻訳機能を使うためのものですが、変数を渡すこともできます。
WordPress5からはむしろ『変数渡し』以外に使い道はありません。
- action値は、PHP, jsファイルの両方で使う。
- ajaxのurlはphpのwp_**関数を使うほうが良い。
- wp_localize_script()を使ってjsに変数を渡す。(直書きしない)
jsファイルのコーディング
今回は、キャッシュファイルをクリアする非同期リクエストをJavaScriptからAjaxで送信します。
jsファイルの内容です。
(function($) {
$(function() {
$('#clear-cache').on('click', function(){
"use strict";
$.ajax({
type: "POST",
url: localize.ajax_url,
dataType: 'text',
data: {
action: localize.action
}
}).done(function(data, textStatus, jqXHR) {
outputMsg(data);
}).fail(function() {
outputMsg('cache clear error!!');
});
});
})
})(jQuery)
htmlクリックイベントのajax通信を想定しています。
<button id="clear-cache">キャッシュのクリア</button>
ポイントはひとつです。
action: localize.action
ここで指定するactionは、サーバー(PHP)が受信するときにリクエストを判別するのに使います。
PHPプログラムでも使うのでオブジェクト変数を使いました。WordPressのPHP関数にはurl関数が豊富に用意されているので、ajax_urlもローカライズしています。
url: localize.ajax_url,
outputMsg()は、処理結果のメッセージをHTMLに出力するオリジナル関数です。ここでは省略します。
Ajaxのリクエスト処理はこれでおわりです。
サーバの処理(phpのコーディング)
今度は、Ajaxのリクエストの受信処理です。キャッシュファイルを削除して結果を返します。ここはPHPプログラムです。
サンプルコードです。
add_action('wp_ajax_clear_cache', function() {
$cache_file = '../cache/11111111111111111.cache';
$success = __('Complete clear cache');
$error = __('Clear cache failer');
$result = '';
if(file_exists($cache_file)) {
if(unlink($cache_file)) {
$result = $success;
} else {
$result = $error;
}
} else {
$result = $success;
}
echo $result;
die();
});
ポイントは3つです。
アクション文字列はadd_action()のハンドル名に使う。
JavaScriptに返す値はechoを使う。
処理の最後にdie()を実行。
Ajax通信の振り分け
不思議に思いませんか?なぜ、ajaxリクエストがこの関数で受け取れるのか?と。
その秘密はadd_action()です。
ajaxのリクエストでactionを送りました。
clear_cache
です。この値は、アクションフックのハンドル名
wp_ajax_****
の****です。この文字列を一致させて、ajaxが送るリクエストを受信します。
actionの文字列はオリジナルでなければなりません。他のajax通信と競合するからです。
actionがちがえば複数のAjax通信もできます。
ajaxリクエストのactionの値を受信処理のアクション・ハンドル名に使う
JavaScriptに結果を返す
WordPressのAjaxの返しはechoで行う
functionのreturnは使えません。returnあるなし関係なく、0を返します。
処理の最後のdie()
必ずreturn 0;を返すので、ajaxの処理結果に0がついてしまいます。これを避けるためdie()でPHPプログラムを強制終了させます。
これで、WordPressのAjax処理が完成しました。
クラスに処理を入れよう!
jsファイルのキュー登録と、ajax受信処理はクラスにまとめたほうがいいです。action文字列はどちらでも使うのでひとつの変数で管理しましょう。
class Clear_Cache_Ajax {
$action = 'clear_cache';
function __construct() {
$this->enqueue();
$this->response();
}
private function enqueue() {
$action = $this->action;
add_action( 'admin_enqueue_scripts', function() use ( $action ) {
$handle = 'my_ajax_handle';
$js_url = plugins_url( 'my-plugins/js/clear-cache.js', __FILE__ );
wp_register_script( $handle, $js_url, [ 'jquery' ], '', true);
$localize = [
'ajax_url' => admin_url( 'admin-ajax.php' ),
'action' => $action,
];
wp_localize_script( $handle, 'localize', $localize );
wp_enqueue_script( $handle );
});
}
private function response() {
$handle = 'wp_ajax_' . $this->action;
add_action( $handle, function() {
$cache_file = '../cache/11111111111111111.cache';
$success = __('Complete clear cache');
$error = __('Clear cache failer');
$result = '';
if(file_exists($cache_file)) {
if(unlink($cache_file)) {
$result = $success;
} else {
$result = $error;
}
} else {
$result = $success;
}
echo $result;
die();
});
}
}
/*----------------
Ajax通信を使う。
-----------------*/
new Clear_Cache_Ajax(); // <--- クラスインスタンスを作るだけ。
このクラスはまだ未完成です。actionを動的にすることで汎用的なAjax通信クラスにスケールアップできます。
このクラスを改修して完成度を高めるチャレンジしてみてください。
ここではクラスの作り方を紹介しているわけではないのでこの辺にしておきます。また、セキュアなajax処理があるのですが実装していません。
くわしくはこちらをどうぞ。