Делаем свою контактную форму на WordPress с нуля

Я — большой поклонник создания разных вещей с нуля. Есть много различных плагинов, охватывающих широкий спектр задач, однако я все же предпочитаю проектировать функционал конкретно под свои нужды.

Зачем я это делаю? Я не хочу возиться с пользовательским интерфейсом плагинов. К тому же, очень часто плагин включает в себя дополнительные возможности, которые на практике оказываются невостребованными. С помощью написания своих собственных решений сделать можно гораздо больше, чем с помощью готовых плагинов.

Свой функционал – это определенный опыт. Вы всегда будете знать, что именно он делает, какие задачи помогает решить. К тому же, вы сможете закрепить свои навыки, и впоследствии реализовать что-то более сложное.

Почему просто не воспользоваться плагинами?

Плагины выступают не самым подходящим решением для простых контактных форм по следующим причинам:

  • Плагин несет в себе гораздо больше возможностей, чем вы нуждаетесь;
  • Использование пользовательского интерфейса для создания простой контактной формы является излишним;
  • Понимание всех деталей создания формы очень важно для вашего опыта и вашего мышления;
  • Стандартные стили надоели до тошноты;

Этот список при желании можно продолжить.

Я ненавижу громоздкий пользовательский интерфейс. Я ненавижу плохой опыт взаимодействия, и особенно ненавижу перебор с функциональностью. «Ненавижу» — сказано слишком сильно, но посмотрите сами: сегодня плагины, предлагающие создание контактных форм, словно соревнуются между собой за звание самого полнофункционального решения. И в итоге мы имеем следующие результаты:

contact-form-7

Или еще хуже:

wp-contact-form

Но мне нужны все эти настройки!

Неужели? Это уже не Web 2.0. Комплексные формы отпугивают клиентов.

Увидев огромное число полей, клиент просто бросит заполнять форму. Такое происходит постоянно. Вообще, пользователи Интернета редко на чем-нибудь заостряют внимание. Их очень просто отвлечь. Поэтому вы должны сделать форму как можно более простой и доступной, чтобы людям не пришлось заполнять миллион полей.

Что является самым важным?

Имя, адрес электронной почты, сообщение и проверка на спам. Правда, мне кажется, было лишним это объяснять.

Заполнить эти четыре поля – проще простого. Так зачем же усложнять контактную форму? Если нет острой необходимости, то дополнительные поля вводить не стоит.

Если люди захотят оставить свой телефонный номер и адрес, они могут сделать это и в самом сообщении.

Создавать все с нуля – это так сложно!

Нет, естественно. Если вы будете терпеливы, то чтение всего руководства (и усвоение материала) займет у вас максимум полчаса. Нам понадобится создать:

  1. Произвольный шаблон.
  2. Немного PHP-кода.

Этого будет достаточно. Мы зададим отображение формы, установим проверку на спам, реализуем уведомление администратора по почте, а также поблагодарим клиента за его сообщение. Вот сам итог.

Первые шаги

Как и всегда, я начну со свежей сборки WP. Придерживаясь хорошей практики, я создам дочернюю тему TwentyTwelve, содержащую только таблицу стилей и шаблон произвольной страницы. Вы можете вытащить произвольный шаблон страницы, вставить его в любую из ваших существующих тем, и он будет прекрасно работать (кроме некоторых CSS модификаций).

В wp-content/themes создадим новую папку contact-form. В ней создадим два файла — style.css и page-contact-us.php.

В файл style.css вставим следующее:

/*
Theme Name:     Contact Form Page Template
Theme URI:      http://wpmu.org/
Description:    A super simple, self-contained contact form you can drop into your existing theme. 
Author:         Harley
Author URI:     http://premium.wpmudev.org/
Template:       twentytwelve
Version:        0.1
*/
 
@import url("../twentytwelve/style.css");

Закомментированные строки можно изменить по своему выбору.

Теперь нам нужно активировать тему на тестовом сайте.

contact-form-theme-active-700x604

Следующий шаг – создание страницы с названием «Contact Us». Эта страница напрямую связана с шаблоном page-contact-us.php, который мы создали ранее. Такое решение взято не из головы — оно основано на структуре шаблонов WP. Файл page-about-us.php будет автоматически использоваться для вывода на экран страницы About Us. Очень удобно!

create-page-contact-us-700x604

Если вы создали шаблон page-contact-us.php и оставили его пустым, то при посещении вашей новой страницы Contact Us вы… ничего не увидите! Будет красоваться чистая страница.

Все в порядке! Внесите в шаблон следующий код, чтобы Contact Us выглядела как обычная страница:

<?php get_header(); ?>
 
  <div id="primary" class="site-content">
    <div id="content" role="main">
 
      <?php while ( have_posts() ) : the_post(); ?>
 
          <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
 
            <header class="entry-header">
              <h1 class="entry-title"><?php the_title(); ?></h1>
            </header>
 
            <div class="entry-content">
              <?php the_content(); ?>
 
              <p>FORM CODE GOES HERE</p>
 
            </div><!-- .entry-content -->
 
          </article><!-- #post -->
 
      <?php endwhile; // end of the loop. ?>
 
    </div><!-- #content -->
  </div><!-- #primary -->
 
<?php get_sidebar(); ?>
<?php get_footer(); ?>

contact-form-back-to-normal-700x604

Теперь у нас есть базовая страница. Самое время поместить на нее простую форму.

Замените параграф FORM CODE GOES HERE следующим кодом:

<style type="text/css">
  .error{
    padding: 5px 9px;
    border: 1px solid red;
    color: red;
    border-radius: 3px;
  }
 
  .success{
    padding: 5px 9px;
    border: 1px solid green;
    color: green;
    border-radius: 3px;
  }
 
  form span{
    color: red;
  }
</style>
 
<div id="respond">
  <?php echo $response; ?>
  <form action="<?php the_permalink(); ?>" method="post">
    <p><label for="name">Name: <span>*</span> <br><input type="text" name="message_name" value="<?php echo $_POST['message_name']; ?>"></label></p>
    <p><label for="message_email">Email: <span>*</span> <br><input type="text" name="message_email" value="<?php echo $_POST['message_email']; ?>"></label></p>
    <p><label for="message_text">Message: <span>*</span> <br><textarea type="text" name="message_text"><?php echo $_POST['message_text']; ?></textarea></label></p>
    <p><label for="message_human">Human Verification: <span>*</span> <br><input type="text" style="width: 60px;" name="message_human"> + 3 = 5</label></p>
    <input type="hidden" name="submitted" value="1">
    <p><input type="submit"></p>
  </form>
</div>

Извините меня за встроенные стили! Они используются только для вывода сообщений об ошибочном/успешном выполнении, и для удобства мы их разместили в одном файле. Поместите стили в свой файл style.css.

Что мы делаем в данном фрагменте кода? Сначала мы выводим переменную $respond, которую мы рассмотрим чуть позже.

Затем идут обычные теги формы. Обратите свое внимание на то, атрибут value этих тегов заполняется через переменную  $_POST. Это нужно для того, чтобы данные не терялись даже в случае некорректного ввода каких-либо полей формы пользователем.

Также имеется скрытый элемент input, который позволяет проверять, отправил пользователь что-нибудь или нет. Я рассмотрю это позже.

Я добавил звездочки рядом с каждым полем, чтобы показать, что эти поля являются обязательными для заполнения.

Если вы сохраните этот код и обновите страницу, то получите красивую контактную форму.

nice-looking-form-700x716

Логика

Логика, положенная в основу отправки данных формы, довольно проста. Есть несколько действий, которые надо реализовать:

  1. Генерация ответа и сообщения (основанная на валидации).
  2. Валидация.
  3. Отправка электронного письма.

Генерация ответа

Чтобы сохранить чистоту и ясность PHP-кода, мы поместим переменную $response в форму. Тем самым мы постараемся отделить логику от представления.

Мы должны написать функцию, которая внесет в переменную $response фидбэк, полученный на этапе валидации.

В вершину файла page-contact-us.php перед get_header() вставим следующее:

<?php
   
  //response generation function
  $response = "";
 
  //function to generate response
  function generate_response($type, $message){
     
    global $response;
 
    if($type == "success") $response = "<div class='success'>{$message}</div>";
    else $response = "<div class='error'>{$message}</div>";
     
  }
?>

Отлично. Пока что данная функция довольно ограничена в плане своих действий. Если у вас есть некоторые знания в области PHP, то вы поймете, что она: а) создает пустую переменную $response, б) заполняет ее тем, что было передано в переменной $message, в зависимости от состояния $type, которое будет либо ошибкой, либо успехом.

Теперь, когда мы создали валидацию, мы можем вызывать generate_response() в любом случае (не важно, успех это или ошибка), передавать сообщение (скажем, недопустимый Email), и это сообщение будет выдано сразу над формой.

Некоторые переменные, которые нам понадобятся

Для создания качественной контактной формы нам нужны три группы переменных:

  • Переменные для сообщений валидации
  • Переменные для элементов ввода формы
  • Переменные для функции PHP mail()

Процесс валидации будет использовать все эти группы для проверки правильности ввода, отправки электронного письма и уведомлении пользователя об отправленном сообщении.

Под функцией generate_response() введем следующие 12 переменных:

//response messages
$not_human       = "Human verification incorrect.";
$missing_content = "Please supply all information.";
$email_invalid   = "Email Address Invalid.";
$message_unsent  = "Message was not sent. Try Again.";
$message_sent    = "Thanks! Your message has been sent.";
 
//user posted variables
$name = $_POST['message_name'];
$email = $_POST['message_email'];
$message = $_POST['message_text'];
$human = $_POST['message_human'];
 
//php mailer variables
$to = get_option('admin_email');
$subject = "Someone sent a message from ".get_bloginfo('name');
$headers = 'From: '. $email . "rn" .
  'Reply-To: ' . $email . "rn";

Предназначение этих групп понятно. Группа Response Message хранит в переменных все наши сообщения обратной связи.

Переменные User Posted Variables хранят данные, полученные из полей формы. Переменная $_POST содержит в себе всю информацию, переданную через форму.

Наконец, мы задаем несколько переменных, которые требуются функции mail() для указания некоторых данных при отправке письма.

Валидация

Это самый сложный момент. Нам необходимо проверить наличие всех возможных проблем самым коротким и быстрым способом. Для этого нужно использовать нескольких вложенных if/else операторов.

Проверяем по порядку:

  1. Передал ли пользователь форму (используя скрытое поле).
  2. Если нет, то проверяем, прошел ли он проверку (правильно ли он выполнил математическое действие).
  3. Если все передано, проверяем email адрес.
  4. Если все передано, проверяем присутствие имени и сообщения (ибо они требуются).
  5. Если все предыдущее верно, отправляем email.

Давайте подробнее рассмотрим этот пункт.

Человеческая проверка

Это достаточно простой шаг. Если пользователь может правильно ввести результат математического действия, значит он является человеком, а не ботом. Если вы посмотрите на нашу форму, то увидите поле с уравнением: ? + 3 = 5. Очевидно, если значение не равно 2, пользователь должен получить ошибку. Если оно равно 2, то тогда идем дальше. После групп переменных вставьте следующее:

if(!$human == 0){
  if($human != 2) generate_response("error", $not_human); //not human!
  else {
     
    //validate email
    //validate presence of name and message
    //send email
  }
} 
else if ($_POST['submitted']) generate_response("error", $missing_content);

Если человеческая проверка не равна нулю, то мы генерируем соответствующий ответ. Если она равна нулю, то ввод был некорректен. Последняя строка проверяет, было ли отправлено скрытое поле, и если это было сделано, то тогда выдается другая ошибка.

Здесь мы тестируем два случая: пустой контент и человеческая проверка.

Если вы попробуете отправить пустую форму, то получите сообщение об ошибке.

first-error-message-700x604

Хорошо! Если вы введете что-то, кроме 2, в строку проверки на спам, то вы также получите ошибку.

Следующая часть валидации – проверка email. Теперь мы знаем, что форму заполнял человек, а не бот, потому нам надо убедиться, что почтовый адрес представлен правильно.

Для простой реализации данного шага мы будем использовать PHP-функцию filter_var(), которая имеет несколько валидационных моделей. Мы будем использовать модель FILTER_VALIDATE_EMAIL.

Заменим три строки с комментариями в середине нашей валидации следующим кодом:

//validate email
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
  generate_response("error", $email_invalid);
else //email is valid
{
  //validate presence of name and message
  //send email
}

Здесь мы проверяем переменную $email, является ли она корректным email-адресом. В противном случае выдаем на экран ошибку.

email-invalid-700x604

Проверяем присутствие имени и сообщения. Для этого мы будем использовать PHP-функцию empty(), которая возвращает true или false в зависимости от того, пуста или нет переданная ей переменная.

//validate presence of name and message
if(empty($name) || empty($message)){
  generate_response("error", $missing_content);
}
else //ready to go!
{
  //send email
}

Наконец, осталось отправить электронное письмо. Как только вся наша валидация будет выполнена, мы воспользуемся функцией mail() для отправки письма на наш электронный адрес. Также мы сгенерируем ответ в случае успеха и в случае неудачи.

Заменим комментарий send email следующим кодом:

$sent = mail($to, $subject, $message, $headers);
if($sent) generate_response("success", $message_sent); //message sent!
else generate_response("error", $message_unsent);//message wasn't sent

Готово! Теперь у вас есть полнофункциональная контактная форма.

Если вы введете все должным образом, то получите сообщение о том, что форма была успешно заполнена, и электронное письмо было отправлено.

message-sent-700x604

Как видите, создание своей собственной контактной страницы – не такая тяжелая задача, чтобы доверять ее плагинам. Вы можете значительно усложнить данный код, что зависит от ваших навыков. К тому же, теперь вы знаете, как вообще работает контактная форма!

Исходник темы с контактной формой.

Источник: wpmu.org

Блог про WordPress
Комментарии: 18
  1. Alexander

    Проблема в том, что при обновлении страницы (F5) письмо отправляется повторно, и так далее…

    ЗЫ:
    Кстати никто не знает как отправлять ещё и файлы?

  2. Юрий

    Как то никак.
    Зачем писать, это вставь, это замени, это перепиши, это дополни.
    Думаю лучше былобы залить эти файлы, чтобы можно их скачать. А потом обьснить что и где необходимо заменить для конкретного пользователя.
    Не понятно как создать страницу. Если я ее хочу назвать не About Us а по другому, то что?
    Не понравилось.!!!

    1. Дмитрий (автор)

      В самом конце статьи прикреплен архив со всеми файлами. Все разжевано до безобразия.

  3. Жанна

    Вы правы в том, что плагины совсем не всегда подходят для решения конкретной задачи. Так для решения своей я перепробовала уже огромную кучу плагинов, но все они во-первых перегружены абсолютно ненужным мне функционалом, во-вторых — ровно то, что мне надо если и есть в них, то в виде платного дополнения или платной версии.
    Но ёпрст! Какие нафиг 40$ за возможность публикации данных заполнения всего-то одной формы в виде постов в определённую рубрику?!
    И даже ваша статья посвящена отправке мыла, но мне этого не нужно!
    Всё что мне нужно: страница с текстом требований для вступления в сообщество людей, внизу которого форма заявки на вступление, по отправке данных из которой создаётся пост в рубрике «Вступление/Заявки», в комментах к которому должно идти обсуждение кандидатуры.
    Весь инет перерыла, но такая простейшая задача похоже никого до меня не интересовала.
    Может вы чем поможете мне в этом?

  4. Fi

    Автор какой- то задрот

  5. Николай

    Ой, да ну весь этот код. Лучше плагин установить https://ru.wordpress.org/plugins/ucalc/ и не заморачиваться, любые формы можно строить под любой дизайн сайта

    1. Дмитрий (автор)

      Можно плагином, но некоторые любят без плагинов все делать, вручную.

  6. Сергей

    Добрый день! Спасибо за Ваш полезный код! Подскажите, пожалуйста, как можно передать в Вашу контактную форму ссылку на кнопку «Сделать заказ» (каждый товар будет представлен в виде записи в WordPress). Очень интересно оформить процесс заказа товара через Ваш скрипт. Я сделал такую кнопку <input type="button" value="Заказать товар" onclick="location.href='contact.htm/?tovar='», но дальше я хочу передать имя записи в Вашу Контактную форму. Помогите, пожалуйста!

    1. Дмитрий (автор)

      Здравствуйте, форма не наша, это перевод руководства. Могу только сориентировать по шагам:
      — получаете данные записи (заголовок, ID или еще что-то) из БД.
      — подгружаете эти данные в textarea в вашей форме.

      Вообще, для продажи цифровых товаров лучше брать плагин Easy Digital Downloads.
      Для продажи реальных товаров — WooCommerce.

  7. Сергей

    Большое спасибо!

  8. Сергей

    Дмитрий а где определение самой переменной $POST
    ругается undefined index: message_name…

    1. Дмитрий (автор)

      Посмотрите в исходнике в самом низу статьи по ссылке. Там весь код целиком, должно быть без ошибок.

  9. Анатолий

    Очень полезный материал! Добавил себе в закладки, очень пригодится. А мне проще все-таки с помощью плагинов создавать, недавно как раз нашел интересную подборку unetway.com/blog/wordpress-plugins-create-forms С плагинами все же меньше времени на создание формы уходит.

  10. Владимир SEO спец

    Благодарю за инфу. Не хватает форме дизайна( а так шик!

  11. Марат

    Все это круто. Но как размещать форму НА ЛЮБОЙ СТРАНИЦЕ или ЗАПИСИ? Просто так страница с формой не интересна. Да, из нее можно сделать страницу Контакты. Хочется на все страницы

    1. Вадим

      Шаблон отдельный можно создать и подключать его к каждой странице. Либо если это авто всплывающая форма, то в футер куда-нибудь разместить да и все. Я таким образом через stepform.io/ru ставил форму, в футер запихнул. Но окна всплывающее пользователи не очень любят, поставил в хедер кнопку и при клике открывается теперь.

  12. Илья

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

    1. Дмитрий (автор)

      Здравствуйте, комментария достаточно вполне. Спасибо!

Добавить комментарий для Сергей Отменить ответ

Получать новые комментарии по электронной почте.