WordPressの公開用サイトでAjaxを実装する方法を、サンプルコードを使って説明します。
WordPressは、Ajaxを公開用サイトで使うのをあまり想定していません。でも方法はあって、とてもかんたんです。
WordPressは公開サイトでのAjax実装は想定していない?
WordPressは、Ajaxで通信するURLが決まっています。
***/admin-ajax.php
しかし、adminとファイル名ついているように、公開サイトで使うのを想定していません。
WordPressはCMS(コンテンツ・マネージメント・システム)なので、プログラミングの知識があまりなくてもWebサイトが作れるのを強みにしています。
Ajaxを実装するくらいプログラミングできるなら、ほかのWebフレームワークの方がいいでしょう。このことから公開サイトのカスタム実装を想定していなかったのだと思います。
じゃあ、WordPressの公開サイトでAjaxは使えないのか? といえばそうではありません。
admin-ajax.phpとは別のphpファイルを使うとちょっとめんどうなので、ここは強引に、admin-ajax.phpを使って公開サイトでAjaxを実装します。
管理画面のAjax実装とほぼ同じ
公開サイトのAjaxは、管理画面の実装方法とほぼ同じです。
WordPressの管理画面のAjaxは、
スクリプトのキュー登録(PHP)。
JavaScriptでリクエスト送信処理。
PHPでリクエスト受信処理。
の3つ。
このなかで、公開サイトのAjaxとのちがいはたった1行で、PHPのリクエスト受信処理のadd_action()のところだけです。
今回のサンプルコードは『WordPressでAjaxを使う(管理画面 編)』を使います。
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は適宜変更。ここではプラグインファイルを想定。)
アクションフックの 'admin_enqueue_scripts' を 'wp_enqueue_scripts' に変更します。
JavaScriptのコードに変更はありません。
(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>
つぎは、ajax受信処理を見てみましょう。
サーバの処理(phpのコーディング)
まず、管理画面のAjaxリクエスト受信処理です。
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();
});
無名関数をやめて、add_actionをもうひとつ追加します。
function my_clear_cache() {
// 処理は割愛。
}
add_action('wp_ajax_clear_cache', 'my_clear_cache');
add_action('wp_ajax_nopriv_clear_cache', 'clear_cache');
フック名が"wp_ajax_nopriv_***"のadd_actionを追記するだけ。これだけです。
"wp_ajax_nopriv_***"は、サイトで管理するユーザーのログインを必要としない閲覧者にもAjaxを許可するもの。
正確には公開サイト用とは言えませんが代用できます。
クラスに処理を入れよう!
ajaxの処理は、キュー登録と受信した後処理をまとめたほうがいいです。クラスオブジェクトにしましょう。
class Clear_Cache_Ajax {
$is_publish = false;
$action = 'clear_cache';
function __construct( $is_publish = false ) {
$this->enqueue();
$this->action();
}
private function enqueue() {
$action = $this->action;
$handle = $this->is_publish ? 'wp_enqueue_scripts' : 'admin_enqueue_scripts';
add_action( $handle, function() use ( $action ) {
$handle = 'my_ajax_handle';
// urlの取り方は適宜変更。方法は割愛。
$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 action() {
$handle = 'wp_ajax_' . $this->action;
$handle_publish = 'wp_ajax_nopriv_' . $this->action;
$function = 'response';
add_action( $handle, [ $this, $function ] );
if ( $this->is_publish ) {
add_action( $handle_publish, [ $this, $function ] );
}
}
public function response() {
$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処理があるのですが実装していません。
くわしくはこちらをどうぞ。
オリジナルのAjaxリクエストURLを作るには
リクエストURLにadminが入るのが気持ち悪い、イヤなら別のphpファイルを作ります。
ただしWordPressは、リクエストを受信してからHTMLを作るまでの処理の流れが内部で出来上がっています。
しかし、Ajax通信ではHTML作成は不要です。
公開サイト用のAjaxリクエストURLを受信したとき、どこかのタイミングでAjax通信の独自処理へ方向転換させないといけません。
タイミングをまちがえると、WordPressでよく使うDBアクセスの関数などが使えなくなるので、注意が必要です。
そのためにはWordPressの処理の流れの理解が必要ですが、それがめんどくさいです。
また、xmlやjson、text形式のレスポンスを返すこともあるので、それを実装するのもめんどうです。
- 公開サイト用のAjax通信は、管理画面用を流用できる。
- カスタムのAjax通信用のURLを作成するとき、まずWordpressの処理の流れの理解が必要。
オリジナルURLのサンプルコードを作成中です。完成次第、追記します。