Создание контактной формы без плагина
Я новичок в разработке для WordPress и устал бороться с Contact Form 7, чтобы стилизовать его так, как мне нужно. Возможно ли и не считается ли "плохой практикой" разместить HTML-форму на странице контактов и отправлять данные на PHP-страницу, которая обрабатывает отправку формы? Или так просто не делают?

Это моя очень простая реализация контактной формы:
class WPSE_299521_Form {
/**
* Конструктор класса
*/
public function __construct() {
$this->define_hooks();
}
public function controller() {
if( isset( $_POST['submit'] ) ) { // Кнопка отправки
$full_name = filter_input( INPUT_POST, 'full_name', FILTER_SANITIZE_STRING );
$email = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_STRING | FILTER_SANITIZE_EMAIL );
$color = filter_input( INPUT_POST, 'color', FILTER_SANITIZE_STRING );
$accessories = filter_input( INPUT_POST, 'accessories', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
$comments = filter_input( INPUT_POST, 'comments', FILTER_SANITIZE_STRING );
// Отправка письма и редирект на страницу "Спасибо"
}
}
/**
* Отображение формы
*/
public function display_form() {
$full_name = filter_input( INPUT_POST, 'full_name', FILTER_SANITIZE_STRING );
$email = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_STRING | FILTER_SANITIZE_EMAIL );
$color = filter_input( INPUT_POST, 'color', FILTER_SANITIZE_STRING );
$accessories = filter_input( INPUT_POST, 'accessories', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
$comments = filter_input( INPUT_POST, 'comments', FILTER_SANITIZE_STRING );
// Пустой массив по умолчанию
$accessories = ( $accessories === null ) ? array() : $accessories;
$output = '';
$output .= '<form method="post">';
$output .= ' <p>';
$output .= ' ' . $this->display_text( 'full_name', 'Имя', $full_name );
$output .= ' </p>';
$output .= ' <p>';
$output .= ' ' . $this->display_text( 'email', 'Email', $email );
$output .= ' </p>';
$output .= ' <p>';
$output .= ' ' . $this->display_radios( 'color', 'Цвет', $this->get_available_colors(), $color );
$output .= ' </p>';
$output .= ' <p>';
$output .= ' ' . $this->display_checkboxes( 'accessories', 'Аксессуары', $this->get_available_accessories(), $accessories );
$output .= ' </p>';
$output .= ' <p>';
$output .= ' ' . $this->display_textarea( 'comments', 'Комментарии', $comments );
$output .= ' </p>';
$output .= ' <p>';
$output .= ' <input type="submit" name="submit" value="Отправить" />';
$output .= ' </p>';
$output .= '</form>';
return $output;
}
/**
* Отображение текстового поля
*/
private function display_text( $name, $label, $value = '' ) {
$output = '';
$output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';
$output .= '<input type="text" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '">';
return $output;
}
/**
* Отображение поля textarea
*/
private function display_textarea( $name, $label, $value = '' ) {
$output = '';
$output .= '<label> ' . esc_html__( $label, 'wpse_299521' ) . '</label>';
$output .= '<textarea name="' . esc_attr( $name ) . '" >' . esc_html( $value ) . '</textarea>';
return $output;
}
/**
* Отображение радио-кнопок
*/
private function display_radios( $name, $label, $options, $value = null ) {
$output = '';
$output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';
foreach ( $options as $option_value => $option_label ):
$output .= $this->display_radio( $name, $option_label, $option_value, $value );
endforeach;
return $output;
}
/**
* Отображение одной радио-кнопки
*/
private function display_radio( $name, $label, $option_value, $value = null ) {
$output = '';
$checked = ( $option_value === $value ) ? ' checked' : '';
$output .= '<label>';
$output .= ' <input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $option_value ) . '"' . esc_attr( $checked ) . '>';
$output .= ' ' . esc_html__( $label, 'wpse_299521' );
$output .= '</label>';
return $output;
}
/**
* Отображение чекбоксов
*/
private function display_checkboxes( $name, $label, $options, $values = array() ) {
$output = '';
$name .= '[]';
$output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';
foreach ( $options as $option_value => $option_label ):
$output .= $this->display_checkbox( $name, $option_label, $option_value, $values );
endforeach;
return $output;
}
/**
* Отображение одного чекбокса
*/
private function display_checkbox( $name, $label, $available_value, $values = array() ) {
$output = '';
$checked = ( in_array($available_value, $values) ) ? ' checked' : '';
$output .= '<label>';
$output .= ' <input type="checkbox" name="' . esc_attr( $name ) . '" value="' . esc_attr( $available_value ) . '"' . esc_attr( $checked ) . '>';
$output .= ' ' . esc_html__( $label, 'wpse_299521' );
$output .= '</label>';
return $output;
}
/**
* Получение доступных цветов
*/
private function get_available_colors() {
return array(
'red' => 'Красный',
'blue' => 'Синий',
'green' => 'Зеленый',
);
}
/**
* Получение доступных аксессуаров
*/
private function get_available_accessories() {
return array(
'case' => 'Чехол',
'tempered_glass' => 'Закаленное стекло',
'headphones' => 'Наушники',
);
}
/**
* Определение хуков плагина
*/
private function define_hooks() {
/**
* Добавление действия для отправки письма
*/
add_action( 'wp', array( $this, 'controller' ) );
/**
* Добавление шорткода для отображения формы
*/
add_shortcode( 'contact', array( $this, 'display_form' ) );
}
}
new WPSE_299521_Form();
После вставки кода вы можете использовать шорткод [contact]
для его отображения.

@user8463989 - это можно добавить в файл functions.php вашей дочерней темы... вы ведь работаете с дочерней темой, верно?

Странно, но после того как я нашел этот ответ, у меня появилась возможность использовать этот код в качестве отправной точки. Очень хорошо.

Хорошая реализация. Где я могу управлять действием формы, то есть куда отправляется форма?

Все плагины для форм ужасны, просто потому что формы обычно очень сложно правильно запрограммировать, особенно когда администратор сайта должен иметь возможность их проектировать.
Нет ничего плохого в том, чтобы написать форму самостоятельно, просто вам, вероятно, придётся воссоздавать то, что другие уже усовершенствовали или, по крайней мере, заложили хорошую основу (форматирование писем, хранение в базе данных и, вероятно, многое другое).
Так что всё действительно зависит от ваших конкретных требований. Если гибкость не требуется, и отправки email достаточно, то написать свою форму должно быть проще, чем "бороться" с плагинами.

Моя самая большая проблема — это попытки стилизовать чекбоксы и радио-кнопки с помощью Contact Form 7 или любого другого плагина для контактных форм. Это медленно убивает меня, поэтому я подумал просто использовать HTML-форму и PHP для отправки данных.

@user8463989, возможно, стоит попробовать другой плагин. На мой взгляд, CF7 слишком базовый, но я никогда им не пользовался, так что, может быть, просто недостаточно знаком с ним, чтобы критиковать. У всех плагинов есть свои особенности, ни один не идеален.

Поскольку вы не выполняете CRUD-операции с базой данных, я не вижу причин не делать так. Я уже делал подобное, используя шаблон страницы для обработки формы и указывая в атрибуте action
контактной формы ссылку на него: action="<?php echo home_url( 'slug-shablona-dlya-obrabotki-formy' ); ?>"
.
Альтернативный вариант — использовать саму запись пользовательского типа для обработки, например: action="<?php echo get_the_permalink();?>"
(для работы get_the_permalink()
страница должна быть одиночной записью, проверяемой через is_single() || is_singular()
).
