ContactForm7のselect選択肢を記事タイトルから自動生成する方法:WordPress
ContactForm7のselect選択肢をWordPressの記事タイトルから自動生成する方法をご紹介します。
口コミフォーム等に便利で、記事を追加・削除しても、フォーム側を毎回手で直す必要が無くなります。
今回は特定カテゴリ【店舗一覧(スラッグ:shop、ID:2)】の記事のタイトル一覧を出力する前提。
目次
ContactForm7側
ContactForm7側は自動生成したい個所に
[shop_select* menu-shop]
のようなコードを入れます。
funcsions.phpに入れるコード
テーマのfunctions.php等に、
/**
* Contact Form 7: 店舗一覧カテゴリ(shop)の記事タイトルを
* select項目として自動出力する独自フォームタグ
*/
add_action('wpcf7_init', 'my_cf7_add_shop_select_tag');
function my_cf7_add_shop_select_tag() {
wpcf7_add_form_tag(
array('shop_select', 'shop_select*'),
'my_cf7_shop_select_tag_handler',
array('name-attr' => true)
);
}
function my_cf7_shop_select_tag_handler($tag) {
if (empty($tag->name)) {
return '';
}
$tag = new WPCF7_FormTag($tag);
$name = $tag->name;
$hangover = wpcf7_get_hangover($name);
$validation_error = wpcf7_get_validation_error($name);
$class = 'wpcf7-form-control wpcf7-select';
if ($tag->is_required()) {
$class .= ' wpcf7-validates-as-required';
}
if ($validation_error) {
$class .= ' wpcf7-not-valid';
}
// カテゴリ shop の通常投稿を取得
$posts = get_posts(array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'category_name' => 'shop',
));
$options = array();
$options[] = '<option value="">クチコミするお店(必須)</option>';
if (!empty($posts)) {
foreach ($posts as $shop_post) {
$title = get_the_title($shop_post->ID);
$selected = selected($hangover, $title, false);
$options[] = sprintf(
'<option value="%1$s"%2$s>%3$s</option>',
esc_attr($title),
$selected,
esc_html($title)
);
}
} else {
$options[] = '<option value="">店舗がありません</option>';
}
$atts = array(
'name' => $name,
'class' => $class,
'aria-invalid' => $validation_error ? 'true' : 'false',
);
if ($tag->is_required()) {
$atts['aria-required'] = 'true';
$atts['required'] = 'required';
}
$attr_html = '';
foreach ($atts as $key => $value) {
$attr_html .= sprintf(' %s="%s"', $key, esc_attr($value));
}
$html = '<span class="wpcf7-form-control-wrap" data-name="' . esc_attr($name) . '">';
$html .= '<select' . $attr_html . '>';
$html .= implode('', $options);
$html .= '</select>';
$html .= $validation_error;
$html .= '</span>';
return $html;
}
//必須チェック
add_filter('wpcf7_validate_shop_select', 'my_cf7_validate_shop_select', 10, 2);
add_filter('wpcf7_validate_shop_select*', 'my_cf7_validate_shop_select', 10, 2);
function my_cf7_validate_shop_select($result, $tag) {
$tag = new WPCF7_FormTag($tag);
$name = $tag->name;
if (empty($name)) {
return $result;
}
$value = isset($_POST[$name]) ? trim(wp_unslash($_POST[$name])) : '';
if ($tag->is_required() && $value === '') {
$result->invalidate($tag, '店舗を選択してください。');
}
return $result;
}
でOK
うまく出ない場合の確認ポイント
1. 投稿タイプがpostではない場合
もし「店舗一覧」が通常投稿ではなく、カスタム投稿タイプならpost_typeを変更する必要があります。
たとえばshopというカスタム投稿タイプならこうです。
'post_type' => 'shop',
その場合、
category_name => 'shop'
は不要です。
2. カテゴリ(shop)が通常投稿のカテゴリではない場合
通常投稿のカテゴリなら今回のコードでOKです。
もし独自タクソノミーなら、tax_queryに変える必要があります。
3. 並び順を公開日順にしたい場合
今はタイトル順です。新しい順ならこう変えます。
'orderby' => 'date', 'order' => 'DESC',
記事ページでは選択肢を非表示にする場合
各記事ページでいちいちその記事を選択させるのは手間ですので、
もし記事ページではその記事が選択されている状態にしつつ選択肢を非表示にしたい場合は
functions.phpのコードを
add_action('wpcf7_init', 'my_cf7_add_shop_select_tag');
function my_cf7_add_shop_select_tag() {
wpcf7_add_form_tag(
array('shop_select', 'shop_select*'),
'my_cf7_shop_select_tag_handler',
array('name-attr' => true)
);
}
function my_cf7_shop_select_tag_handler($tag) {
if (empty($tag->name)) {
return '';
}
$tag = new WPCF7_FormTag($tag);
$name = $tag->name;
$hangover = wpcf7_get_hangover($name);
global $post;
$current_post_id = 0;
$current_title = '';
if (get_queried_object_id()) {
$current_post_id = get_queried_object_id();
} elseif (isset($post->ID)) {
$current_post_id = $post->ID;
}
if ($current_post_id) {
$current_title = get_the_title($current_post_id);
}
$is_shop_single = false;
if (
$current_post_id &&
is_singular('post') &&
has_category('shop', $current_post_id)
) {
$is_shop_single = true;
}
$validation_error = wpcf7_get_validation_error($name);
$class = 'wpcf7-form-control wpcf7-select';
if ($tag->is_required()) {
$class .= ' wpcf7-validates-as-required';
}
if ($validation_error) {
$class .= ' wpcf7-not-valid';
}
// 店舗記事ページでは hidden
if ($is_shop_single) {
$value = '';
if ($hangover !== '') {
$value = $hangover;
} elseif ($current_title !== '') {
$value = $current_title;
}
$html = '<span class="wpcf7-form-control-wrap" data-name="' . esc_attr($name) . '">';
$html .= '<input type="hidden" name="' . esc_attr($name) . '" value="' . esc_attr($value) . '">';
$html .= $validation_error;
$html .= '</span>';
return $html;
}
// それ以外では select
$posts = get_posts(array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'category_name' => 'shop',
));
$options = array();
$options[] = '<option value="">クチコミするお店(必須)</option>';
if (!empty($posts)) {
foreach ($posts as $shop_post) {
$title = get_the_title($shop_post->ID);
$selected = selected($hangover, $title, false);
$options[] = sprintf(
'<option value="%1$s"%2$s>%3$s</option>',
esc_attr($title),
$selected,
esc_html($title)
);
}
}
$html = '<span class="wpcf7-form-control-wrap" data-name="' . esc_attr($name) . '">';
$html .= '<select name="' . esc_attr($name) . '" class="' . esc_attr($class) . '" aria-invalid="' . ($validation_error ? 'true' : 'false') . '">';
$html .= implode('', $options);
$html .= '</select>';
$html .= $validation_error;
$html .= '</span>';
return $html;
}
add_filter('wpcf7_validate_shop_select', 'my_cf7_validate_shop_select', 10, 2);
add_filter('wpcf7_validate_shop_select*', 'my_cf7_validate_shop_select', 10, 2);
function my_cf7_validate_shop_select($result, $tag) {
$tag = new WPCF7_FormTag($tag);
$name = $tag->name;
if (empty($name)) {
return $result;
}
$value = isset($_POST[$name]) ? trim(wp_unslash($_POST[$name])) : '';
if ($tag->is_required() && $value === '') {
$result->invalidate($tag, '店舗を選択してください。');
}
return $result;
}
のように変更すればOKです。
WordPressのおすすめ参考書
bookfan 1号店 楽天市場店
¥3,300 (2026/03/21 01:45時点 | 楽天市場調べ)



