2018年01月15日
カスタムフォームに編集機能を追加する
PowerCMS のカスタムフォーム機能 (Contact Form アドオン) による投稿フォームは、サイトの利用者から見たとき次のような動きをする設計になっています。(「ContactFormScript
」は PSGI のエンドポイントや CGI のファイル名を示す CMS の環境変数で、既定値は「mt-contactform.cgi
」になります。)
- 入力画面から
ContactFormScript
へ HTTP POST で入力内容を確認する。 - 入力内容にエラーが有れば
ContactFormScript
が入力済みの入力画面を表示する。 - 入力内容にエラーが無ければ
ContactFormScript
が確認画面を表示する。 - 確認画面から
ContactFormScript
に HTTP POST で投稿する。 - 入力内容にエラーが無ければ
ContactFormScript
が完了画面を表示する。
そのため、入力画面で正しい内容を入力してエラー無く確認画面が表示されると、あとは [投稿] ボタンを押して確認した内容を投稿するという流れになります。
もしカスタムフォームについてよくわからなければ当サイトのお問い合わせフォームを利用して、一通りの流れを実際に確認できます。確認画面では [投稿] ボタンを押さず、誤って投稿なさらぬよう注意してください。
今回は「確認した内容をやはり編集し直す」ための [編集] ボタンを確認画面に設けて、機能を追加する方法をご紹介します。
サイトの利用者から見たときのフォームの動作についておさらいしますと、既定の設計ではおおよそ次のような流れになっています。
- 入力、確認、投稿、完了。
- 入力、修正、確認、投稿、完了。
ここに編集機能を追加すると、おおよそ次のような流れに変わります。
- 入力、確認、編集、確認、投稿、完了。
- 入力、確認、編集、修正、確認、投稿、完了。
- 入力、修正、確認、編集、確認、投稿、完了。
フォームの HTML を変更する
編集機能を追加するにあたり、カスタムフォームの「フォーム項目」を抱えるフォームの HTML について、おおまかに2つの変更をします。
1つ目の変更は、編集するか否かを判断するための目印とするパラメーターをフォームに追加します。
既存でない任意のパラメーター名を付けることが可能ですが、ここでは「edit
」とし、これを編集パラメーターと呼ぶことにします。
2つ目の変更は、フォームの HTML からパラメーターの要素 <input name=__mode>
と送信用ボタンの要素 <input type=submit>
を削除し、その代わりに状況に応じて [確認] ボタン、または [編集] と [投稿] ボタンを追加します。削除したパラメーターは、送信用のボタンとして <input>
要素の代わりに <button>
要素を利用することで、フォームの投稿者が選択できるようにし、押されるボタンに応じて分岐しています。
編集ボタン (<button name=__mode value=confirm>
) は確認画面で入力内容にエラーが無く、入力内容に編集パラメーターが無いという2つの条件を満たすときに限り、編集パラメーター (<input type=hidden name=edit value=1>
) と併せて出力します。
確認画面での条件分岐には、入力内容にエラーが無ければ暗黙のテンプレート変数「confirm_ok
」の値が「1
」となることを利用し、編集パラメーターの有無はテンプレート変数「request.edit
」の値で判断します。
削除した送信ボタン (<input type=submit>
) の代わりに、確認ボタン (<button name=__mode value=confirm>
) または投稿ボタン (<button name=__mode value=submit>
) のいずれかを出力します。編集ボタンと同じ条件で、確認画面では投稿ボタンを出力し、それ以外は確認ボタンを出力します。
今回はこれら2つの変更をするため、フォームの HTML を regex_replace
モディファイアにより書き換える方法と、フォームの HTML を構築するためのテンプレートを編集する方法を説明します。いずれかの方法で実現できます。
regex_replace
モディファイアにより書き換える方法
種類がフォームのカスタムフィールドを作成し、テンプレートタグが「MTPageForm
」のとき、regex_replace
モディファイアで前述の変更を行うテンプレートの例です。
<MTSetVarBlock name="regex_replace_1">/<input(?=[^>]*\s+name\s*=\s*(["']?)__mode\1)[^>]+>/</MTSetVarBlock> <MTSetVarBlock name="regex_replace_2_1">/<input(?=[^>]*\s+type\s*=\s*(["']?)submit\1)[^>]+>/</MTSetVarBlock> <MTSetVarBlock name="regex_replace_2_2"><button name=__mode value=confirm>確認</button></MTSetVarBlock> <MTIf name="confirm_ok"> <MTUnless name="request.edit"> <MTSetVarBlock name="regex_replace_2_2"> <input type=hidden name=edit value=1> <button name=__mode value=confirm>編集</button> <button name=__mode value=submit>投稿</button> </MTSetVarBlock> </MTUnless> </MTIf> <MTPageForm regex_replace="$regex_replace_1","" regex_replace="$regex_replace_2_1","$regex_replace_2_2" >
module_mtml.tmpl
を編集する方法
フォームのカスタムフィールドのテンプレートタグ (MTPageForm
) は、状況に応じて処理結果が様々に変化しますが、その実体はアドオンのファイル (addons/ContactForm.pack/tmpl/module_mtml.tmpl
) に書かれているテンプレートです。このファイルを addons/ContactForm.pack/alt-tmpl/module_mtml.tmpl
としてコピーし、編集することでパラメーターの要素を削除したり、送信ボタンの要素を追加したりとフォームの HTML を自由にできるほか、ファイル編集ではなく管理画面からフォーム毎にテンプレート管理できるようにする ContactFormMTML プラグインが利用できます (参考: PowerCMS ブログ『ContactFormの複数のベーステンプレートをモジュール管理可能にするプラグイン』)。ただしこのプラグインを導入すると、tools/rebuild-archives
などによる再構築処理でフォーム用のテンプレートタグ (MTPageForm
) がフォームの HTML を出力しなくなってしまう問題があるのでご注意ください。
PowerCMS 4.33 に同梱の Contact Form アドオン 2.13 の module.mtml
を使用した書き換えを例に説明します。
基本的には regex_replace
モディファイアで変更する方法と同じく、29行目を削除します。
<input type="hidden" name="__mode" value="<mt:If name="confirm_ok">submit<mt:Else>confirm</mt:If>" />
68行目付近の
<mt:If name="confirm_ok"> <input type="submit" value="<$mt:Trans phrase="Submit" component="ContactForm"$>" /> <mt:Else> <input type="submit" value="<$mt:Trans phrase="Confirm" component="ContactForm"$>" /> </mt:If>
を
<mt:SetVarBlock name="button_html"> <button name="__mode" value="confirm"><$mt:Trans phrase="Confirm" component="ContactForm"$></button> </mt:SetVarBlock> <mt:If name="confirm_ok"> <mt:Unless name="request.edit"> <mt:SetVarBlock name="button_html"> <input type="hidden" name="edit" value="1" /> <button name="__mode" value="confirm"><$mt:Trans phrase="Edit" component="ContactForm"$></button> <button name="__mode" value="submit"><$mt:Trans phrase="Submit" component="ContactForm"$></button> </mt:SetVarBlock> </mt:Unless> </mt:If> <mt:Var name="button_html">
のように変更します。
フォーム項目のテンプレートを変更する
フォームの HTML を変更したら、次は個々のフォーム項目を編集機能に対応させます。
システムのプラグイン設定 (?__mode=cfg_plugins&blog_id=0
) で Contact Form Config プラグインの設定を開き、テンプレートの枠にある「text」から「date-and-time」まで9項目のテンプレートについて、冒頭部分の
<$mt:SetVar name="display_description" value="0"$> <mt:unless name="field_mode"> <$mt:SetVar name="display_description" value="1"$> </mt:unless> <mt:if name="field_error"> <$mt:SetVar name="display_description" value="1"$> </mt:if>
を
<$mt:SetVar name="display_description" value="0"$> <mt:unless name="field_mode"> <$mt:SetVar name="display_description" value="1"$> <mt:else name="field_error"> <$mt:SetVar name="display_description" value="1"$> <mt:else name="request.edit"> <$mt:SetVar name="display_description" value="1"$> <$mt:SetVar name="confirm_ok" value="0"$> </mt:unless>
のように変更します。編集パラメーター (request.edit
) があるときはテンプレート変数「confirm_ok
」を意図的に無効化して、フォーム項目を編集可能な状態にします。これで新規作成するフォーム項目が編集機能に対応しました。すでに作成済みのフォーム項目も、同様にして対応できます。
動作を確認する
入力画面からフォームに入力して確認へ進むと、確認画面のフォームに [編集] ボタンが表示されました。
確認画面で [編集] ボタンを押すと、確認した内容が入力済みの状態で元の入力画面と同様の編集画面が表示されました。
さあ帰ろう。
- カテゴリー
- テンプレート作成Tips