※2018.10.05追記: カスタマイズコードの記述を修正しました。
この記事で書いていること
記事前半では「Jazzy Forms」のインストールから基本的な使い方を、
後半では、プラグインのソースコードを一部編集して、
「かゆいところに少しでも手を届かせるようなこと」を書いています。
お仕事で、
「WordPressで作成するサイトに、お客さんからの注文見積を請けるフォームを作りたい」
「見積結果はお客さんとシステム管理者にメール送付したい」
「注文選択の状況に応じて、画面上でリアルタイムに合計金額を算出させたい」
というオーダーを頂きまして。

WordPressなんだからプラグイン探せば何かあるやろー
と思って探してみたものの、要件にドンピシャにハマるプラグインが見つからず。
(多分探し方が悪いんだろうなー……)
そんな最中に見つけたのが、今回ご紹介する「Jazzy Forms」プラグイン。
早速試してみましょうかね。
なお、今回は検証にあたり、Mac上に開発環境を整えています。
方法は、以前こちらの記事にて紹介致しました。
また、Macのローカル開発環境からメールの送信を検証するにあたり、
以下の記事を参考にさせて頂きました。
プラグイン「Jazzy Forms」をインストールし有効化する
WordPressの管理コンソールにアクセスし、
プラグインの新規追加画面から「Jazzy Forms」で検索。
「最終更新が随分昔だし最新版のWPでテストされてないよ!」
と、いきなり不穏なメッセージが出力されます。
導入は自己責任で。
ここでは、このまま「インストール」→「有効化」まで進めます。
ダッシュボードのメニューに「Forms」が追加され、
次のような画面を表示できれば成功です。
画面項目を作っていこう
ここでは、上記のようなフォームの作成を試しています。
フォームの構成としては、
表示名 | 型 | id |
---|---|---|
名前 | テキスト | name |
メールアドレス | テキスト | |
商品選択 | ラジオボタン | item |
ギフトラッピング | チェックボックス | gift |
合計 | 自動計算 | total |
送信 | (ボタン) | submit |
といった構成で仕上げていきます。
各要素には「Title」と「ID」という属性を必ず持たせます。
「Title」は画面表示で、「ID」は自動計算やメール送信でそれぞれ使います。
上記はラジオボタン要素での設定画面です。
ここでは、「画面上で商品Aを選択したら100円」、
「商品Bを選択したら200円」といった挙動にしていきます。
チェックボックスの設定画面です。
「ギフトラッピングにチェックを入れたら50円」
「チェックを入れない場合は0円」としています。
自動計算項目の設定画面です。
先ほどの「商品選択(item)」と「ギフトラッピング(gift)」の合計値を加算し、
計算結果をリアルタイムに画面出力します。
固定ページにショートコードを貼って、フォーム画面完成!
「Forms」画面の「General」タブにて、
投稿や固定ページでフォームを呼び出すためのショートコードを発行できます。
今回は、シンプルに固定ページにフォームだけが存在ページを出力してみます。
cssなどで手を加えない状態で、上記のようなフォームが生成出来ました。
「商品A」がデフォルトで選択済みであるため、
「合計」の値の初期値が「100」となっています。
見積結果をメール送信!……ここで問題が発覚する
「Forms」画面の「email」タブにて、
メール送信した際の、メッセージ内容やタイトルなどの設定が出来ます。
ここでも、先ほどフォーム生成時に設定したIDを用います。
さて、上記の設定でメールを送ってみましょうかね。
上記のメールは、
「名前に”Yusuke Kobayashi”を入力し」
「商品選択で”商品B”を選択し」
「ギフトラッピングにチェックを入れ」
送信ボタンをクリックした際にシステムが自動送信したものです。
……おわかり頂けただろうか。
上記のケースにて、
「商品Bを選択した」「ギフトラッピングにチェックを入れた」
ということが、メール文面からは確認出来ないということを……
「商品Bを選択したから、そのvalue値の200を出力」
「ギフトラッピングにチェックを入れたから、そのvalue値の50を出力」
と、ひじょう(非常/非情)に雑なメッセージになってしまっています。

でもよぉ……ここまで出来るんなら、
何かしら「選択した項目名」を出力する方法……あるやろ……
ないんだな、それが。
探したんだよ!必死に!!
それこそ海外のフォーラムの書き込みとかも!
でも「そういう出力出来ないんですね。残念です。」みたいな書き込みしか無かったんだよ!!
※2018/10/05 後日談
WordPressプラグイン「Jazzy Forms」で見積送信ページを作るためのカスタマイズ備忘録https://t.co/3CrewUzCBX
こんなまどろっこしいカスタマイズしなくてもOutputフィールドで「Label(id)」すればいけるじゃねーか!
みんなちゃんと公式ドキュメントは読もうな!fxxk!https://t.co/YGEZ6dAGcx
— KOBA@田舎をハッキングする男 (@KOBA5884) 2018年10月5日
ソースコードをカスタマイズして応急処置
フォームの作成や自動計算まわりの使い勝手が良かっただけに、
ここでこのプラグインを手放して別のを探すのは大変惜しい……
というわけで、どうにかソースコード側をカスタマイズして、
チェックボックス・ラジオボタン・ドロップダウンでの、
選択項目の項目名を送信メールに挿入できないか、検証していきます。
以下、Jazzy Formsのソースコードは、
「/wp-content/plugins/jazzy-forms/」
に配置されているものとして話を進めていきます。
まず、最終的にどこでメール送信の処理が記述されているか探してみました。
ソースとしては「core/Mail.php」ファイルの、
「jzzf_send_email($email)」関数にて処理を実行しています。
この$emailの変数には、
既にメールテンプレートと各値がドッキングされた状態のデータが格納されています。
では、この関数はどこから呼び出されているのか。
「front/ctrl-email.php」の「jzzf_ctrl-email()」という処理の中で、
「if(jzzf_send_email($replaced))」という形での呼び出しが確認できます。
ここで引数に渡している「$replaced」ですが、直前の行にて値を定義しています。
$replaced = jzzf_apply_email_templates($email, $_REQUEST['values']);
この行で、 emailテンプレートと、実際の値をドッキングしているようです。
テンプレートに挿入する値は、$_REQUEST[‘values’]に格納されています。($email はテンプレート)
さて、ここまでくれば、

どうやらサーバにREQUESTを投げる時点で値を加工すれば
任意の値をねじ込めそうだぞ……
ということがわかってきます。
そうなると、自ずと改修対象のファイルが見えてきますね。
次はjavascriptを漁ってみましょう。
「front/jazzy-forms.js」の「send_email($button)」(100行目付近)にて、
ajaxでvaluesの値をPOSTしていることが確認できます。
このvaluesは以下のコードにて定義されています。
values[key] = calculator.placeholder(graph.email[key]);
values配列に対して任意のkeyとvalを仕込むように改修すれば、
メールテンプレートに指定したkeyに対してそのvalを埋め込むことができそうです。
というわけで、「send_email($button)」を、以下のように改修してみました。
function send_email(button) {
// add 20180605 start
var form_id = graph.form.id;
var key_select = '';
var input_id_header = 'jzzf_' + form_id + '_';
var input_id = '';
var input_label = '';
var key_org = '';
// add 20180605 end
if(!validate()) {
return;
}
set_message(button, graph.form.email.sending);
var values = {};
for(var key in graph.email) {
// add 20180605 start
key_org = key.replace(new RegExp('_select'+"$"), "");
if(key_org != key){
if(typeof graph.data[key_org] !== 'undefined'){
input_id = input_id_header + key_org;
key_select = key_org + '_select'; // add 20180605
if($('input[name='+ input_id +']:checked').length === 1){
// ラジオボタンの場合
input_id = $('input[name='+ input_id +']:checked')[0].id;
input_label = $('[for="' + input_id + '"]')[0].innerHTML;
values[key_select] = input_label;
}else if(document.getElementById(input_id).checked === true){
// チェックボックスの場合
input_label = $('[for="' + input_id + '"]')[0].innerHTML;
values[key_select] = input_label;
}else if(document.getElementById(input_id).type === "select-one"){
input_label = document.getElementById(input_id).value;
values[key_select] = input_label;
}else{
values[key_select] = '';
}
}
}else{
values[key] = calculator.placeholder(graph.email[key]);
}
// add 20180605 end
}
var obj = $.ajax({
/*以下略*/
やっていることとしては、
フォームの画面要素から、実際に選択された値のラベルテキストを抽出し、
その値を「xxx_select」とするキーに格納しています。
フォームにて何が選択されているのかについて、
もっといい取得方法があれば良かったのですが、思いつかなかったのて、暫定でこれで。
DOM操作が得意な人が書いたらもっと綺麗に書けるはずです。
とはいえ、コード読めない人にとっては「なんのこっちゃ」って話なので、
実際に挙動がどう変わるのか、見ていきましょう。
上記ソースを適用した状態で、WordPressのForms管理画面に戻ります。
送信するemailの設定画面を、次のように編集します。
{item_select}やら{gift_select}やら、form設定の画面には存在しない要素を設定しています。
が、これらは、先ほどのコード改修により、ちゃんとメール本文に欲しい文字を入れてくれるようになります。
この状態で、商品選択に「商品B」を選択し、
「ギフトラッピング」にチェックを入れた状態でメールを送信してみます。
この通り。
ラジオボタンで選択した項目や、チェックボックスでチェックを入れた項目について、
それぞれに該当するラベルの値を取得し、メール送信のためのパラメータとして持たせることに成功しました。
* * *
とまぁ、こんな感じで。
「やりたいことを8割実現してくれるプラグインを見つけた」ってときに、
「残り2割を実現するために既存プラグインをカスタマイズする」のか、
「残り2割も実現してくれる別のプラグインを探す旅に出る」のか、
「いっそ1から10まで自分で作る」のか。
今回の場合は、他に良さそうなプラグインが見つからなかったので、
実現したいことに一番近しいアプリを改修する形での実装に至りました。
これをやっていく過程で、嫌でも他人が書いたコードを読むことになるので、
色々発見があったり、勉強になったりと、オマケが得られるのが地味にお得だったりします。
こういう形で、少しずつですがスキルを積んでいきたいですね。