Contact Form 7のセレクトボックスをタームやカスタム投稿から自動生成する

公開日
最終更新日
Contact Form 7 セレクトボックスの選択肢をタクソノミーのタームやカスタム投稿のタイトルから自動生成

リクルートサイトのエントリーフォームで、「希望職種」や「雇用形態」のセレクトボックスの選択肢を、サイト側の登録内容と常に一致させておきたい——求人が増減するたびにフォームを手直しするのは手間ですし、更新漏れも起こりがちです。

結論から言うと、Contact Form 7のセレクトボックスの選択肢を、タクソノミーのタームやカスタム投稿のタイトルから自動生成することで、この問題を解決できます。この記事では、functions.phpに追記する2パターンのコードを解説します。

たとえば上のようなエントリーフォームで、雇用形態や希望職種をカスタムタクソノミーで登録しておき、そのタームをセレクトボックスの選択肢として自動で出力すれば、フォームとサイトの内容が常に一致します。求人の追加・削除に、フォームが自動で追従してくれるのが利点です。

タクソノミーのタームから自動生成する

1つ目は、カスタムタクソノミーのターム一覧を選択肢にするパターンです。functions.phpに次のコードを追記します。

// Contact Form 7 セレクトボックスの選択肢をタクソノミーのターム一覧から自動生成
add_filter('do_shortcode_tag', function ($output, $tag, $attr) {
    if ('contact-form-7' === $tag || 'contact-form' === $tag) {

        $id   = 10;               // コンタクトフォームの ID
        $name = 'select-recruit'; // セレクトボックスの名前
        $tax  = 'recruit_type';   // タクソノミーのスラッグ

        if ($id == $attr['id']) {
            $terms = get_terms($tax, array('hide_empty' => false));
            if (!empty($terms) && !is_wp_error($terms)) {
                $options = '<option value="">選択してください</option>';
                foreach ($terms as $term) {
                    $options .= '<option value="' . esc_attr($term->name) . '">' . esc_html($term->name) . '</option>';
                }
                $output = preg_replace('/(<select .*?name="' . $name . '".*?>)(.*?)(<\/select>)/i', '${1}' . $options . '${3}', $output);
            }
        }
    }
    return $output;
}, 10, 3);

このコードは、do_shortcode_tagフィルターでフォームの出力HTMLを受け取り、指定したnameのセレクトボックスの中身を、タームから生成した<option>で置き換えています。$id(フォームID)・$name(セレクトボックス名)・$tax(タクソノミーのスラッグ)の3つを、自分の環境に合わせて書き換えれば動作します。

Contact Form 7側には、置き換え先となる空のセレクトボックス(例:[select select-recruit])を用意しておきます。あとはタームを追加・編集するだけで、選択肢が自動で更新されます。

なお、get_terms()は、WordPressのバージョンによってはget_terms(array('taxonomy' => $tax, 'hide_empty' => false))という新しい書き方が推奨されます。上記のコードでタームが取得できない場合は、この形も試してみてください。

カスタム投稿のタイトルから自動生成する

2つ目は、カスタム投稿のタイトル一覧を選択肢にするパターンです。求人名(=カスタム投稿のタイトル)をそのまま選択肢にしたい場合に便利です。

// Contact Form 7 セレクトボックスの選択肢をカスタム投稿のタイトルから自動生成
function job_selectlist($tag, $unused)
{
    // セレクトボックスの名前が 'select-job' かどうか
    if ($tag['name'] != 'select-job') {
        return $tag;
    }

    // get_posts() でセレクトボックスの中身を作成する
    $args = array(
        'numberposts' => -1,
        'post_type'   => 'job', // カスタム投稿タイプを指定
        'orderby'     => 'ID',  // 並び順 = セレクトボックス内の表示順
        'order'       => 'ASC'
    );

    $job_posts = get_posts($args);

    // 投稿がなければそのまま戻す
    if (!$job_posts) {
        return $tag;
    }

    // セレクトボックスに foreach で入れる
    foreach ($job_posts as $job_post) {
        $tag['raw_values'][] = $job_post->post_title;
        $tag['values'][]     = $job_post->post_title;
        $tag['labels'][]     = $job_post->post_title;
    }

    return $tag;
}
add_filter('wpcf7_form_tag', 'job_selectlist', 10, 2);

こちらはwpcf7_form_tagフィルターを使い、フォームタグそのものに選択肢を追加する方式です。セレクトボックス名がselect-jobのときだけ、get_posts()で取得したカスタム投稿(job)のタイトルを、選択肢として1つずつ差し込んでいます。

2つの方法の使い分け

どちらの方法も「サイトの登録内容とフォームの選択肢を自動で一致させる」という目的は同じですが、選択肢の元にするデータが異なります。

  • 雇用形態や希望職種など、分類(カテゴリー的なもの)を選ばせたい → タクソノミーのターム
  • 個々の求人名や商品名など、投稿そのものを選ばせたい → カスタム投稿のタイトル

扱いたいデータがタクソノミーか投稿かで、使うフィルターを選べば迷いません。どちらも一度設定すれば、あとは管理画面での登録・編集だけで選択肢が自動更新されるので、運用の手間がぐっと減ります。

2つのコードで使っているフィルターが違う点も押さえておくと理解が深まります。do_shortcode_tag出力されたHTMLを後から書き換える方式、wpcf7_form_tagフォームタグが作られる段階で選択肢を組み込む方式です。前者はHTMLを正規表現で置換するぶん対象の指定がやや繊細で、後者はContact Form 7の仕組みに沿って値を渡すため素直に扱えます。どちらでも実現できますが、迷ったらカスタム投稿の例で使ったwpcf7_form_tag方式のほうが扱いやすいでしょう。

まとめ

  • タームを選択肢にするならdo_shortcode_tagで出力HTMLを置き換える
  • カスタム投稿のタイトルを選択肢にするならwpcf7_form_tagでフォームタグに追加する
  • フォームID・セレクトボックス名・対象のスラッグを環境に合わせて書き換える
  • 一度設定すれば、登録内容の更新に選択肢が自動で追従する

選択肢の自動生成は、更新漏れによる「フォームとサイトの内容の食い違い」を防ぐ、運用面で効果の大きい実装です。求人サイトはもちろん、店舗一覧やサービス一覧など、項目が増減するフォーム全般で活用できます。

IPPEI FUKUTA(株式会社バッズブルー 代表)

IPPEI FUKUTA(株式会社バッズブルー 代表)

WordPress専門のWeb制作者として15年・150サイト以上を担当。現場でつまずいた問題と解決策を、同じ制作者・フリーランスの方に向けて発信しています。無料のWeb便利ツール集「バドツール」を開発・運営中。