- 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細)
プラグインで AJAX を使う
はじめに
Ajax/en (Asynchronous JavaScript And XML)はWebページがページ全体を再読み込みすることなく、一部の情報だけを更新できるようにする技術です。これはWordPressの管理画面において、投稿編集時の自動保存や、新規カテゴリーの追加など、色んなことに使われています。WordPressプラグインの中には、投票機能や地図の更新などにAjaxを使っているものがあります。
この記事はプラグイン開発者を対象とし、プラグインにAjaxを追加する方法について説明します。この記事を読む前に、以下のことについて理解している必要があります:
- Ajax/en - 技術の概要
- プラグインの作成 - プラグインの作成方法
- プラグイン API - フィルターとアクション - それがなんであり、どうやって使うか
- WordPress内の意図したページ・投稿・画面にHTMLを追加する方法 -- たとえば、作成した管理画面にAjaxを追加したい場合は、管理メニューの追加について理解していなければなりません。もし単一の投稿の外観に対してAjaxを追加したい場合、ブログの画面の適切な部分にHTMLを追加するために必要なフィルターとアクションがどれなのか、わからなければいけません。この記事はこうした範囲まではカバーしていません。
- WordPressでAjaxを使うには、クライアントサイドのJavascriptプログラミング、PHPプログラミング、そしてHTMLについての知識も必要です。
おわかりだと思いますが、Ajaxの機能をWordPressの管理画面に追加するのか、それとも公開されている部分に追加するのかによって、プラグインにAjaxを追加する技術は異なります。したがって、この記事ではできるかぎりその二つをわけて取り上げたいと思います(共通項について述べた後ですが)。
Ajaxの基本実装
通常、Ajaxリクエストには3つのステップがあります:
- ユーザーがなにか(クリックやマウスのドラッグなど)をすると、Webページに埋め込まれたJavascriptが反応して"リクエスト"を生成、そして、それをWebサーバ上の任意のURLに送信します。セキュリティ制限により、リクエスト送信先のURLはJavascriptが実行されたファイルと同じWebサイト〔訳注:同じドメイン〕である必要があります。
- Webサーバ側のスクリプトやプログラム(WordPressにおいては、通常複数のPHP関数)はリクエストを処理し、ブラウザに情報を送り返します。
- 送り返された情報はJavascriptを使って表示されます。
残念ながら、AjaxのほとんどはJavascriptです。JavascriptはユーザのWebブラウザ上で実行され、すべてのWebブラウザがAjax通信を同じように実装しているわけではありません。それゆえ、物事を簡単にするために、ほとんどのAjax開発者はテストを重ねられ、クロス・ブラウザ対応済みのライブラリを使用することを選びます。そうしたライブラリは一貫したAPIの元、とあるブラウザの奇妙な振る舞いを標準クラスの中で吸収しています。この記事ではこうしたライブラリの一つであるSACK (Simple Ajax Code-Kit)を使います。これはWordPressの中に含まれています。本文の先の方には(ページの終わりを見てください)、jQueryによるAjaxの実装に関するリファレンスがいくつかあります。jQueryはWordPressに入っているもう一つのライブラリです。コンセプトはほとんど同じですが、構文は少し違います。
それでは、Ajaxリクエストを作り出すSackライブラリとJavascript関数の両方が、Ajaxリクエストを発生さえるページのHTMLのhead部で読み込まれていることを確認しましょう。以下の節では、管理画面とWordPressの公開部分の両方でそれを行う方法を示します。
SACKライブラリを使ってAjaxリクエストを生成する場合、次の情報を与える必要があります。さらい先の節では、管理画面とWordpressの公開部分でこの値がどうなるのかを詳細に見ていきます:
- リクエストURL: Ajaxリクエストを処理するサーバのURL。
- カスタムリクエスト変数: SACKでは任意のリクエスト変数を設定することができ、POSTかGETによってサーバに送信されます。Cookie情報を送ることもできます。
- エラー処理: Ajaxエラーが発生したときに呼び出されるjavascript関数。
デフォルトだと、SACKは、サーバからの戻り値がJavascriptコードであり、戻ってきた時に(非同期で)実行されると仮定します。以下の例では、このデフォルト動作を使うので、Ajaxリクエストを処理するPHP関数は処理結果をJavascriptのコマンドに作り変える必要があります。プラグインで戻り値を別の形式で使いたい場合、SACK Project Home Pageを訪れ、zipファイルをダウンロードし、ドキュメントを呼んでください。その他の方法が明記されているでしょう。
もう一点細かく書くと、Ajaxリクエストを処理するPHP関数はPHPdie関数を使ってJavascriptのエンコードされた情報を返さなければなりません。例:die("javascriptコマンド")
このAjaxの背景を念頭に入れて、次の二つのセクション - WordPressの管理画面でAjaxを使用する例と、WordPressの公開部分でAjaxを使用する例に移ります。二つのセクションは独立しているので、あなたのプラグインに適したセクションだけ呼んでも構いません。
管理画面でのAjax
WordPressの中心的な管理画面にはすでにAjaxが組み込まれているので、あなたのプラグインの管理画面にAjax機能を追加するのは比較的簡単です。このセクションでは、そのやり方を説明します。すでに述べたように、WordPressの公開部分にAjaxを使いたい場合はこのセクションを飛ばしてもかまいません。
WordPressプラグインの管理画面でAjaxを使う例として、地理タグ・プラグインを想定しましょう。投稿に緯度と経度を入力すると、プラグインはWebサービスを利用してその地点の高度を調べます。Ajaxプログラミングのことを考える前に、ユーザが緯度と経度を入力できるフィールドと高度調査のボタン、そして結果を表示する高度フィールドを管理画面に追加する必要があります。この記事では、管理画面にそれらを追加する方法、そしてフィールドの幅、テキスト、スタイルなどを好きなように変更する方法については理解していると仮定します。管理画面のHTMLフォーム内に以下のようなものを入れましょう:
緯度: <input type="text" name="latitude_field" /> 経度: <input type="text" name="longitude_field" /> <input type="button" value="Look Up Elevation" onclick="myplugin_ajax_elevation(this.form.latitude_field,this.form.longitude_field,this.form.elevation_field);" /> 高度: <input type="text" name="elevation_field" id="elevation_field" />
続いて、ボタンのonClickアクションに設定されたJavascript関数myplugin_ajax_elevationを定義する必要があります。これはユーザーの入力値を調べ、SACKでのリクエストを構成し、処理を行うプラグインに送信します。すでに述べたように、このJavascript関数とSACKライブラリは管理画面のHTMLのhead部に読み込まれている必要があります。一番簡単な例はadmin_print_scriptsアクションを使ってすべての管理画面に追加してしまうことです:
add_action('admin_print_scripts', 'myplugin_js_admin_header' ); function myplugin_js_admin_header() // これはPHP関数 { // JavascriptのSACKライブラリをAjaxに使用 wp_print_scripts( array( 'sack' )); // カスタムJavascript関数の定義 ?> <script type="text/javascript"> //<![CDATA[ function myplugin_ajax_elevation( lat_field, long_field, elev_field ) { // 関数本体。後に定義します。 } // Javascript関数myplugin_ajax_elevation終わり //]]> </script> <?php } // PHP関数myplugin_js_admin_header終わり
次のステップはJavascript関数myplugin_ajax_elevationの本文を埋めることです。これはフォームフィールドから緯度と経度を読み取り、SACKでAjaxリクエストを生成し、サーバにリクエストを送信します。上のセクションで紹介したSACKを生成する情報のリストを参考にすると、この例で設定する必要があるのは以下になります:
- リクエストURL: 今からリクエストを送信しようとしているURLは、WordPressの管理システムで定義されたURL(bloghome)/wp-admin/admin-ajax.phpです。これから先の部分で、WordPressに対して特殊なAjaxアクションを加える方法を説明します。これを使えば、リクエストを受け取った時にどのプラグインPHP関数を呼び出せばいいのか、スクリプトに対して教えることができます。アクションは"myplugin_elev_lookup"だということにしておきましょう。
- カスタムリクエスト変数: サーバには緯度と経度を送信する必要があります。また、"アクション"の名前もadmin-ajax.phpスクリプトに対して教える必要があります。クッキーも送らなくてはなりません。ログイン情報が含まれているからです。そして最後に、サーバサイド関数が結果を表示するためのJavascriptを返してきたときのために、高度フィールドのIDを関数に渡さなくてはなりません。
これをすべて行うJavascriptは以下のようになります:
function myplugin_ajax_elevation( lat_field, long_field, elev_field ) { var mysack = new sack( "<?php bloginfo( 'wpurl' ); ?>/wp-admin/admin-ajax.php" ); mysack.execute = 1; mysack.method = 'POST'; mysack.setVar( "action", "myplugin_elev_lookup" ); mysack.setVar( "latitude", lat_field.value ); mysack.setVar( "longitude", long_field.value ); mysack.setVar( "elev_field_id", elev_field.id ); mysack.encVar( "cookie", document.cookie, false ); mysack.onError = function() { alert('Ajax error in looking up elevation' )}; mysack.runAJAX(); return true; } // Javascript関数myplugin_ajax_elevation終わり
この例の最後のステップでは、Ajaxリクエストがサーバに到達したときに起きることを定義しています。すでに述べたように、にリクエストを(bloghome)/wp-admin/admin-ajax.phpに送信しているのですから、"アクション"パラメータは"myplugin_elev_lookup"にしておきます。wp_ajax_*アクションを使うことで、リクエスト受信時にプラグインのどのPHP関数を呼び出すかをWordPressに通知することができます。
PHP関数は高度を調査するサーバに緯度と経度を送り、レスポンスを待ち、結果を解析し、Javascriptコマンドとして結果を返信します。Webリクエスト送信には"Snoopy"Webリクエストクラス(WordPress組み込み)を使いましょう。このようになります:
add_action('wp_ajax_myplugin_elev_lookup', 'myplugin_ajax_elev_lookup' ); function myplugin_ajax_elev_lookup() { // 送信された情報を格納 $lat = $_POST['latitude']; $long = $_POST['longitude']; $field_id = $_POST['elev_field_id']; $units = "FEET"; // SnoopyによるURLリクエストを生成 require_once( ABSPATH . WPINC . '/class-snoopy.php' ); $sno = new Snoopy(); $sno->agent = 'WordPress/' . $wp_version; $sno->read_timeout = 2; $reqURL = "http://gisdata.usgs.gov/XMLWebServices/TNM_Elevation_Service.asmx/getElevation?Y_Value=$lat&X_Value=$long&Elevation_Units=$units&Source_Layer=-1&Elevation_Only=1"; // 高度調査サーバにリクエストを送信 if( !$sno->fetchtext( $reqURL )) { die( "alert('高度調査ホストに接続できませんでした')" ); } // レスポンスを解析 if( !preg_match("|<Elevation>([\d.-]+)</Elevation>|",$sno->results)){ die( "alert('分析結果に高度は含まれていませんでした')" ); } $matches=preg_split( "|<Elevation>([\d.-]+)</Elevation>|",$sno->results); //正規表現のバグ: 情報は返します // 戻り値としてJavascriptを生成 die( "document.getElementById('$field_id').value = " . $matches[1] ); } // myplugin_axax_elev_lookup関数終わり
以上で完了です! エラーの有無やリクエストが正しい場所から行われているかをチェックするなど、もう少し改良の余地はありますが、管理画面にAjaxを追加する手ほどきとしては、以上で十分でしょう。
WordPress公開部分でのAjax
WordPressサイトの公開部分にAjaxを実装するには、管理画面よりも少し特別なことが必要になります。というのも、WordPressそれ自体では公開部分にAjaxを組み込まないからです。とはいえ、そんなに困ることもないでしょう。このセクションでやり方を説明します。上述したとおり、WordPress管理画面にAjaxを使いたい場合は、このセクションを飛ばしても構いません。
例として、ブログの閲覧者に何らか投票や格付けを可能にするプラグイン(投票プラグインや、ポスト・レイティングといってもの)を想定しましょう。ブログの閲覧者が投票を行うと、その票はAjaxによって反映されるので、閲覧者はページの更新を待たなくてもよいのです。投票が登録されたら、現在の総票数が更新されます。この例では、事態をシンプルにするために、投票と表示はテキストベースで行われることとし、WordPress公開部分の適切な部分にHTMLを表示するために、適切なフィルターやアクションが設定されたり、テーマが編集されていると仮定します。追加されたHTMLはこのようになります:
<form> あなたの投票: <input type="text" name="uservote" /> <input type="button" value="Vote!" onclick="myplugin_cast_vote(this.form.uservote,'voteresults');" /> <div id="voteresults"> (PHP関数から出力されるこれまでの総票数) </div> </form>
続いて、ボタンのonClickアクションに設定されるJavascript関数myplugin_cast_voteを定義しましょう。これはユーザが入力した情報を読み取り、SACKでのリクエストを生成し、処理を行うプラグインに送信します。冒頭のセクションで述べたように、このJavascript関数とSACKライブラリはユーザが見ているWebページのHTMLのhead部に読みこまれている必要があります。これを実現する方法の一つとしては、アクションを使ってWordPress投稿画面のすべてに追加してしまうことです(もう少し限定的に読み込ませるために、is_***() 条件分岐タグを使って絞り込むことができます):
add_action('wp_head', 'myplugin_js_header' ); function myplugin_js_header() // this is a PHP function { // Ajax用にSACKライブラリを仕様 wp_print_scripts( array( 'sack' )); // カスタムのJavascriptを定義 ?> <script type="text/javascript"> //<![CDATA[ function myplugin_cast_vote( vote_field, results_div ) { // 関数本体は後で定義します } // javascript関数myplugin_cast_vote終わり //]]> </script> <?php } // PHP関数myplugin_js_header終わり
次のステップは、Javascript関数myplugin_cast_voteの本体部分を埋めることです。これはフォームフィールドから票を読み取り、SACKでのAjaxリクエストを生成し、サーバにリクエストを送信します。上のセクションで紹介したSACKを生成する情報のリストを参考にすると、この例で設定する必要があるのは以下になります:
- リクエストURL: プラグインのPHPファイルにリクエストを送信しなくてはなりません。この項目はプラグインのメインPHPファイルまたは補助ファイルになります。わかりやすくするために、WordPressの標準プラグインディレクトリwp-content/pluginsにある"myplugin_ajax.php"という別ファイルであるとしましょう。
- カスタムリクエスト変数: この例では、票と結果が出力されるdivのIDをサーバに送ればいいだけです。
これを用いると、Javascript関数はこのようになります:
function myplugin_cast_vote( vote_field, results_div ) { var mysack = new sack( "<?php bloginfo( 'wpurl' ); ?>/wp-content/plugins/myplugin_ajax.php" ); mysack.execute = 1; mysack.method = 'POST'; mysack.setVar( "vote", vote_field.value ); mysack.setVar( "results_div_id", results_div ); mysack.onError = function() { alert('Ajax error in voting' )}; mysack.runAJAX(); return true; } // Javascript関数myplugin_cast_vote終わり
この例の最後のステップは、サーバにAjaxリクエストが送信された後に何が起きるかを定義することです。この処理はmyplugin_ajax.phpファイルで行われます。投稿された情報を読み取り、投票が有効からを判断し、データベースに票を追加し、新しい総票数を算定し、ブラウザにレスポンスを戻します。投票の処理はひとまず置いておき、ファイルで行われることを見てみましょう:
<?php // 著者とライセンス情報をここに入れてください // TO DO! // 有効なソースからなるリクエストチェックを入れてください // TO DO! // 送信された情報を読み取ります $vote = $_POST['vote']; $results_id = $_POST['results_div_id']; // 投票を処理するコードを入れてください // この例では、以下のようになります // a) 処理コードはエラーがあった場合、 // グローバル変数$errorをメッセージに設定します。 // b) エラーがなければ、$resultsには結果が出力される // div内に挿入するHTMLを持ちます if( $error ) { die( "alert('$error')" ); } // 戻り値としてのJavascriptを設定 die( "document.getElementById('$results_id').innerHTML = '$results'" ); ?>
これで完了です! エラーチェックや引用符のエスケープ、投票の処理、リクエスト送信元のチェックなど、いくつかやらねばならないことはありますが、WordPressの公開部分にAjaxを使うには、この例で十分でしょう。
より詳細な情報 - 外部リソース
- jQueryを使うWordPressプラグイン開発者のためのシンプルなAjax
- WordPressにおけるjQueryとAjax
- 公開ページにおけるjQueryとAjaxを使ったプラグイン
- あなたのWordPressプラグインにAjaxを導入しよう - 公開部分におけるAjaxを利用したプラグインの例
最新英語版: WordPress Codex » AJAX in Plugins (最新版との差分)