Многие разработчики и владельцы сайтов на WordPress сталкиваются с необходимостью расширить стандартные формы, чтобы собирать более детальную информацию от пользователей. При этом не всегда хочется использовать сторонние плагины, чтобы не перегружать сайт и не создавать потенциальные конфликты. В этой статье мы подробно разберём, как добавить расширенные поля в формы WordPress без плагинов, с примерами кода и рекомендациями по безопасности.
Почему стоит создавать расширенные формы без плагинов
Плагины для форм, такие как Contact Form 7, Gravity Forms или WPForms, действительно удобны и функциональны, но они могут влиять на скорость сайта и создавать лишние зависимости. Кроме того, если у вас нестандартные требования к обработке данных или интеграции с другими сервисами, кастомный код будет более гибким и легким в поддержке.
Создавая форму самостоятельно, вы полностью контролируете HTML, PHP и JavaScript, что позволяет оптимизировать форму под конкретные задачи и интегрировать её с любыми API.
Однако при разработке важно учитывать вопросы безопасности — валидировать и санитизировать вводимые данные, защищать форму от CSRF и спама.
Создание формы с расширенными полями: пример кода
Рассмотрим пример, где мы создадим форму с такими полями, как:
- Текстовое поле с ограничением длины
- Поле для телефона с маской ввода
- Выпадающий список с несколькими вариантами
- Чекбоксы для выбора нескольких опций
- Поле загрузки файла с проверкой формата
Добавим форму в шаблон темы или в отдельный файл, подключенный через get_template_part():
<form method="post" enctype="multipart/form-data" action="">
<label for="wptalk_name">Имя:</label>
<input type="text" id="wptalk_name" name="wptalk_name" maxlength="50" required>
<label for="wptalk_phone">Телефон:</label>
<input type="tel" id="wptalk_phone" name="wptalk_phone" pattern="\+7\d{10}" placeholder="+7XXXXXXXXXX" required>
<label for="wptalk_choice">Выберите опцию:</label>
<select id="wptalk_choice" name="wptalk_choice" required>
<option value="option1">Опция 1</option>
<option value="option2">Опция 2</option>
<option value="option3">Опция 3</option>
</select>
<fieldset>
<legend>Дополнительные услуги:</legend>
<label><input type="checkbox" name="wptalk_services[]" value="service1"> Услуга 1</label>
<label><input type="checkbox" name="wptalk_services[]" value="service2"> Услуга 2</label>
<label><input type="checkbox" name="wptalk_services[]" value="service3"> Услуга 3</label>
</fieldset>
<label for="wptalk_file">Загрузить файл (jpg, png, pdf):</label>
<input type="file" id="wptalk_file" name="wptalk_file" accept=".jpg,.jpeg,.png,.pdf">
<input type="submit" name="wptalk_submit" value="Отправить">
</form>
Обработка данных формы на стороне сервера
Для обработки данных создадим функцию, которая:
- Проверит nonce для защиты от CSRF
- Валидирует и санитизирует пользовательский ввод
- Обработает загрузку файла с проверкой формата и размера
- Выведет ошибки или сохранит данные, например, отправит письмо
add_action('init', 'wptalk_handle_custom_form');
function wptalk_handle_custom_form() {
if (!isset($_POST['wptalk_submit'])) {
return;
}
// Проверка nonce если добавлен (рекомендуется)
// if (!isset($_POST['wptalk_nonce']) || !wp_verify_nonce($_POST['wptalk_nonce'], 'wptalk_form')) {
// wp_die('Ошибка безопасности');
//}
$errors = [];
// Валидация имени
$name = sanitize_text_field($_POST['wptalk_name'] ?? '');
if (empty($name) || mb_strlen($name) > 50) {
$errors[] = 'Введите корректное имя (до 50 символов).';
}
// Валидация телефона
$phone = sanitize_text_field($_POST['wptalk_phone'] ?? '');
if (!preg_match('/^\+7\d{10}$/', $phone)) {
$errors[] = 'Введите телефон в формате +7XXXXXXXXXX.';
}
// Валидация выбора
$choice = sanitize_text_field($_POST['wptalk_choice'] ?? '');
$valid_choices = ['option1', 'option2', 'option3'];
if (!in_array($choice, $valid_choices, true)) {
$errors[] = 'Выберите корректную опцию.';
}
// Валидация чекбоксов
$services = $_POST['wptalk_services'] ?? [];
$valid_services = ['service1', 'service2', 'service3'];
if (!is_array($services) || array_diff($services, $valid_services)) {
$errors[] = 'Выберите корректные услуги.';
}
// Обработка файла
if (!empty($_FILES['wptalk_file']['name'])) {
$file = $_FILES['wptalk_file'];
$allowed_types = ['image/jpeg', 'image/png', 'application/pdf'];
if ($file['error'] !== UPLOAD_ERR_OK) {
$errors[] = 'Ошибка при загрузке файла.';
} elseif (!in_array($file['type'], $allowed_types, true)) {
$errors[] = 'Недопустимый формат файла. Разрешены jpg, png, pdf.';
} elseif ($file['size'] > 2 * 1024 * 1024) { // 2 МБ
$errors[] = 'Файл слишком большой. Максимум 2 МБ.';
} else {
$upload = wp_handle_upload($file, ['test_form' => false]);
if (isset($upload['error'])) {
$errors[] = 'Ошибка загрузки файла: ' . esc_html($upload['error']);
} else {
$file_url = $upload['url'];
}
}
}
if ($errors) {
foreach ($errors as $error) {
echo '<p style="color:red;">' . esc_html($error) . '</p>';
}
return;
}
// Обработка успешных данных, например, отправка письма
$to = get_option('admin_email');
$subject = 'Новая заявка с сайта';
$message = "Имя: $name\nТелефон: $phone\nОпция: $choice\nУслуги: " . implode(', ', $services);
if (!empty($file_url)) {
$message .= "\nФайл: $file_url";
}
wp_mail($to, $subject, $message);
echo '<p style="color:green;">Спасибо! Ваша заявка отправлена.</p>';
}
Добавление маски ввода и улучшение UX с помощью JavaScript
Для поля телефона удобно добавить маску, чтобы пользователь вводил номер в правильном формате. Для этого можно использовать простую библиотеку или написать свой скрипт.
Пример простого маскирующего скрипта:
document.addEventListener('DOMContentLoaded', function() {
var phoneInput = document.getElementById('wptalk_phone');
phoneInput.addEventListener('input', function(e) {
var x = phoneInput.value.replace(/\D/g, '').match(/(\d{0,1})(\d{0,3})(\d{0,3})(\d{0,2})(\d{0,2})/);
phoneInput.value = '+7' + (x[2] ? x[2] : '') + (x[3] ? x[3] : '') + (x[4] ? x[4] : '') + (x[5] ? x[5] : '');
});
});
Также стоит продумать стили и подсказки, чтобы форма была удобной и понятной.
Рекомендации по безопасности и производительности
При работе с кастомными формами важно:
- Использовать
wp_nonce_field()и проверять nonce в обработчике для защиты от CSRF. - Валидировать и санитизировать все входящие данные с помощью функций WordPress:
sanitize_text_field(),esc_html(),wp_handle_upload(). - Ограничивать размер и тип загружаемых файлов.
- Защищать формы от спама — можно добавить скрытые поля, honeypot или интегрировать reCAPTCHA.
- Минимизировать количество запросов и использовать AJAX, если необходимо, для улучшения UX.
Заключение
Добавление расширенных полей в формы WordPress без плагинов — это отличный способ сделать сайт более гибким и легким. Такой подход требует тщательной работы с валидацией, безопасностью и UX, но в результате вы получаете полный контроль над функциональностью.
Если вы хотите расширить функционал с минимальными усилиями, на wpshop.ru есть плагины, которые могут помочь упростить создание форм, например, WPRemark для отзывов и комментариев с расширенными полями.