WordPressで一番使われてるだろうお問い合わせフォームプラグインContact Form7の、
フォーム部分をVue.jsで作り変える必要が出たのでその時に調べた仕様とかのメモ。
コンタクトフォーム記事IDの取得
Contact Form 7はカスタム投稿タイプ wpcf7_contact_form
で記事が作成される。
データベースが変わらないのであればJS内で決め打ちしていいが、環境でデータベースが異なるならIDをWordpress側から受け取るようにする。
get_postsの利用
タイトルやスラッグを元にIDを取得する。
1 2 3 4 5 6 7 | $form = get_posts(array( 'post_type' => 'wpcf7_contact_form', 'post_status' => 'publish', 'title' => 'お問い合わせ' // title // ,'name' => 'contact-form' // slug )); // var_dump($form[0]->ID); |
get_optionの利用
別に設定画面を用意してそこにフォーム記事IDを登録するという手もある。
1 | var_dump((int) get_option( 'wpcf7-form-id' )); |
HTML
input[type=hidden]
で以下3つ必要。
1 2 3 4 | <!-- [contact-form-7 id="123" title="お問い合わせ"] --> < input type = "hidden" name = "_wpcf7" value = "123" > < input type = "hidden" name = "_wpcf7_unit_tag" value = "wpcf7-f123-p1000-o1" > < input type = "hidden" name = "_wpcf7_locale" value = "ja" > |
_wpcf7 の値は上記で取得したコンタクトフォームの記事IDで、ショートコードにIDで記載されるものと同じ。
_wpcf7_locale は言語。
_wpcf7_unit_tag の値はショートコードがHTMLタグに変換される時に生成されるもので、以下の構文で作成する。
wpcf7-f[フォームのID]-p[フォームを埋め込んでる記事ID]-o[記事内のフォーム番号]
※埋め込む記事IDがないなら3番目のpから始まる部分は省略
※記事内のフォーム番号は1から始まる連番。
ex:Vue.js
1 2 | < input type = "hidden" name = "_wpcf7" v-model = "formId" > < input type = "hidden" name = "_wpcf7_unit_tag" v-model = "unitTag" > |
1 2 3 4 5 | computed: { unitTag() { return `wpcf7-f${ this .formId}-p${ this .postId}-o1`; } } |
送信
送信先は/wp-json/contact-form-7/v1/contact-forms/フォーム記ID/feedback
である。
1 2 3 4 5 6 7 8 9 | const formData = new FormData( document.getElementById( 'form' ) ); axios.post(`/wp-json/contact-form-7/v1/contact-forms/${formId}/feedback`, formData) .then(res => { console.log(res); }) . catch (error => { console.log(error); }); |
Response
statusは validation_failed
, acceptance_missing
, spam
, aborted
, mail_sent
, mail_failed
, custom
で、messageは管理画面で設定したもの。
エラーの場合はinvalidFieldsでエラーになっているフォームの情報が帰ってくる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Success { into: "#" , // unit_tag message: "ご利用ありがとうございます。送信が完了しました。" , status: "mail_sent" } // Error { into: "#" , // unit_tag invalidFields: [ { idref: "your-email" , // フォームのname into: "span.wpcf7-form-control-wrap.your-email" //className message: "この項目は入力必須です。" } ], message: "1つ以上のフィールドにエラーがあります。 確認してからもう一度お試しください。" , status: "validation_failed" } |
ex:Vue.js
1 2 3 4 | < form v-on:submit.prevent = "onSubmit" ref = "form" > <!-- ブラウザのバリデーション使わない場合 --> < form v-on:submit.prevent = "onSubmit" ref = "form" novalidate> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | methods: { onSubmit() { if ( typeof window.FormData !== 'function' ) { return ; } const formData = new FormData( this .$refs.form ); axios.post(`/wp-json/contact-form-7/v1/contact-forms/${ this .formId}/feedback`, formData) .then(res => { console.log(res); }) . catch (error => { console.log(error); }); } } |
追加の設定
config.phpに追加するもの
1 2 3 4 5 6 7 8 | // トークンチェックをオフにする define ( 'WPCF7_VERIFY_NONCE' , false); // ContactForm7のJSを読み込まない define ( 'WPCF7_LOAD_JS' , false); // ContactForm7のCSSを読み込まない define ( 'WPCF7_LOAD_CSS' , false); |
以下はContactForm7のスパム判定を変更するフィルター。
テーマのfunctions.phpに追加する。
1 2 3 4 5 6 7 8 9 | add_filter( 'wpcf7_recaptcha_verify_response', function( $is_human, $response_body ) { $score = isset( $response_body['score'] ) ? $response_body['score'] : 0; $threshold = 0.1; $is_human = $threshold < $score; return $is_human; }, 10, 2 ); |