タグアーカイブ Conditional Fields

Contact Form 7のPDF出力で条件分岐ショートコードが効かない時の直し方

Contact Form 7のPDF出力で条件分岐ショートコードが効かない時の直し方

Contact Form 7 から出力する PDF に条件分岐のショートコード([if] や [hide-*] など)が反映されないとき、最も多い原因は Send PDF for Contact Form 7 プラグインが、Conditional Fields のような他プラグインのショートコードを PDF 生成時に評価しないことだ。この問題は、PDF テンプレート内で直接条件分岐を記述する代わりに [_mail_body] タグを使ってメール本文を丸ごと流し込むか、出力直前にショートコードを再評価するフィルターフックで解決できる

なぜ PDF 出力で条件分岐ショートコードが効かなくなるのか

なぜ PDF 出力で条件分岐ショートコードが効かなくなるのか

Send PDF for Contact Form 7 は、フォーム送信時に生成されたデータを PDF テンプレートに差し込んで出力する。このとき、[text-123] のような Contact Form 7 の標準タグは正しく展開されるが、Conditional Fields が提供する [group] や [if] といった条件分岐用のショートコードは、PDF 生成のコンテキストでは実行されないことが多い

理由は主に2つある。ひとつは、これらのショートコードが WordPress の do_shortcode フックに登録されていても、PDF プラグインがテンプレートを処理する段階では、フォームの送信データや条件判定に必要なコンテキストが不足しているケースだ。もうひとつは、Conditional Fields のショートコードが「メール送信時」にのみ動作するように設計されており、PDF 作成時にはそもそも処理の対象外になっているパターンだ

Before(修正前) PDF 内の表示

[if kosten-an-arbeitgeber]この見積は雇用主向けです[/if]

※条件にかかわらずショートコードがそのまま表示される

After(修正後) 同じ場所の表示

この見積は雇用主向けです

※条件に合致したテキストだけが PDF に出力される

修正前 修正後

このデモのように、PDF テンプレート内に [if] や [hide-*] を直書きしても、Send PDF 側で解釈されずに終わってしまう。以前は偶然動いていたとしても、プラグインのバージョンアップで処理順序が変わると即座に壊れる原因になる

プラグイン更新後に突然動かなくなったのはなぜか

プラグイン更新後に突然動かなくなったのはなぜか

「以前は PDF で条件分岐が効いていたのに、更新したら動かなくなった」という声は非常に多い。これは、Send PDF for Contact Form 7 または Conditional Fields for Contact Form 7 の内部実装が変更され、テンプレートの評価タイミングやショートコードの登録順が変わったためだ

具体的には、Send PDF プラグインの旧バージョンでは、PDF テンプレート全体を do_shortcode で処理していたが、パフォーマンスやセキュリティの改善に伴ってその処理が省略されたり、独自の置換処理に切り替わったりすることがある。結果として、Conditional Fields のショートコードが一切処理されなくなる

また、Conditional Fields 側のアップデートで、[if] タグの内部実装が変わり、PDF 出力時に必要なデータが揃わなくなった可能性もある。どちらにせよ、PDF テンプレート内で直接条件分岐を記述する方式は、プラグインのバージョンに依存しやすく、根本的に不安定と言える

[_mail_body] タグでメール本文をそのまま PDF に流し込む

[_mail_body] タグでメール本文をそのまま PDF に流し込む

最も簡単で安全な解決策は、PDF テンプレート内に [_mail_body] を記述することだ。このタグは、Contact Form 7 が送信する「メール本文」をそのまま PDF 内に差し込む。メール本文のほうでは、Conditional Fields の条件分岐が正常に評価されているため、結果的に PDF にも正しい内容が出力される

STEP 1 Contact Form 7 の「メール」タブで、条件分岐を含むメール本文を完成させる
STEP 2 Send PDF のテンプレート編集画面を開き、本文にあたる領域で [_mail_body] とだけ入力する

この方法を使えば、Conditional Fields に限らず、メール本文で動作するあらゆるショートコードが PDF に反映される。ただし、PDF 独自のレイアウトや追加情報(会社ロゴや利用者に合わせた細かな差し込み)が必要な場合は、[_mail_body] の前後に固定の HTML を加えることで対応できる

注意点として、[_mail_body] はメール本文をそのままコピーするため、メール用の改行やスタイルが PDF に持ち込まれる。どうしてもレイアウトを細かく制御したい場合は、次に紹介するフィルターフックを使った方法を選ぶ

functions.php で PDF 生成前に条件分岐を再評価させる

functions.php で PDF 生成前に条件分岐を再評価させる

Send PDF for Contact Form 7 には、PDF の最終的な内容を上書きできるフィルターフックが用意されている。これを利用すれば、テンプレート内の [if] や [hide-*] を手動で再評価できる。テーマの functions.php に次のようなコードを追加すると、Conditional Fields のショートコードが PDF 出力時に正しく展開される

add_filter( 'cf7_send_pdf_template_html', function( $html, $form_id ) {
    // フォームの送信データを取得し、ショートコードを再評価する
    $submission = WPCF7_Submission::get_instance();
    if ( $submission ) {
        $posted_data = $submission->get_posted_data();
        // 一時的に do_shortcode を再度適用
        $html = do_shortcode( $html );
    }
    return $html;
}, 10, 2 );

このコードは、PDF テンプレートが組み立てられた直後に do_shortcode を実行し、[if] や [group] といったショートコードをその場で評価する。投稿データが揃っているため、Conditional Fields の条件判定も正しく動く

ただし、[hide-*] のように独自のショートコードを使っている場合は、そのショートコードがどのプラグインで定義されているかを確認し、該当のプラグインが有効でなければ動作しない。もし自作のショートコードであれば、あらかじめ add_shortcode で登録しておく必要がある

さらに、Send PDF プラグインのバージョンによってはフック名が異なる可能性もあるため、公式ドキュメントを参照し、cf7_send_pdf_template_html の部分を適切なフックに置き換える。このフックが利用できない場合は、wpcf7_before_send_mail などのアクションを使って PDF 生成前にデータを補完する方法もある

よくある質問

[_mail_body] を使うとメールの HTML タグがそのまま PDF に出てしまうのでは?

はい、メールフォーマットが HTML の場合、その HTML が PDF に適用される。多くは問題にならないが、シンプルなテキスト PDF を望むなら、メール設定を「テキスト形式」に切り替えるか、フィルターフックで HTML タグを strip_tags で除去するといった工夫が必要になる

Conditional Fields の [group] ショートコードも [_mail_body] で有効になるのか?

なる。[_mail_body] は、メール送信時に CF7 が最終的に組み立てた本文をそのまま埋め込むため、[group] の条件判定もすでに解決された状態で出力される

functions.php にコードを追加しても PDF が変わらないのはなぜ?

フック名が正しいか、また対象のショートコードが本当に do_shortcode で評価可能な形式かを確認する。Conditional Fields の [if] が内部で別のロジックを使っているレアケースでは、CF7 のメールテンプレート用のフィルター(wpcf7_mail_components など)を利用してメール本文を直接 PDF に渡すほうが確実だ

独自の [hide-*] ショートコードを PDF で動かすにはどうすればいい?

該当のショートコードを定義しているコードがテーマの functions.php にあるなら、そのまま do_shortcode で評価される。もし別のプラグインに依存しているのであれば、そのプラグインが常に有効でなければならない。動作が不安定な場合は、[_mail_body] 方式に切り替えるのが無難だ

この記事のポイント

  • PDF テンプレート内で [if] や [hide-*] が効かないのは、Send PDF がそれらのショートコードを処理しないため
  • [_mail_body] タグを使えば、メール本文ですでに展開された条件分岐結果をそのまま PDF に流し込める
  • functions.php のフックで do_shortcode を再実行すれば、PDF 出力直前に任意のショートコードを動かせる
  • プラグイン更新後に動かなくなったのは、ショートコード処理のタイミングが変わったのが原因
  • 安定運用には[_mail_body]方式を推奨。細かいレイアウトが必要ならフィルターフック方式を使う