TechBlogSD - Все для WordPress и WEB разработки
WEB и WordPress инструкции, новости, обзоры тем и плагинов

Пример отправка формы без с помощью WordPress REST API (2021)

222

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

Но предположим, что мы планируем использовать WordPress как автономную CMS. В этом случае мы в основном будем взаимодействовать с REST API (или GraphQL). Мы полностью несем ответственность за интерфейсную часть, и мы больше не можем полагаться на плагины форм для выполнения тяжелой работы в этой области. Теперь мы на месте водителя, когда дело касается передней части.

Формы были решенной проблемой, но теперь мы должны решить, что с ними делать. У нас есть несколько вариантов:

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

Самый популярный плагин свободной формы, Contact Form 7, имеет конечную точку REST API для отправки, как и известный платный плагин Gravity Forms и другие.

С технической точки зрения нет реальной разницы между отправкой данных формы в конечную точку, предоставляемую службой или плагином WordPress. Итак, мы должны принимать решение по разным критериям. Цена очевидна; после этого будет доступна установка WordPress и его REST API. Отправка на конечную точку предполагает, что она всегда общедоступна. Когда речь идет об услугах, это уже очевидно, потому что мы платим за их доступность. Некоторые настройки могут ограничивать доступ WordPress только к процессам редактирования и сборки. Еще одна вещь, которую следует учитывать, – это место, где вы хотите хранить данные, особенно в соответствии с правилами GPDR.

Когда дело доходит до функций, выходящих за рамки отправки, плагины форм WordPress трудно сопоставить. У них есть своя экосистема, надстройки, способные создавать отчеты, PDF-файлы, легко доступная интеграция с информационными бюллетенями и платежными сервисами. Немногие услуги предлагают так много в одном пакете.

Даже если мы используем WordPress «традиционным» способом с клиентской частью, основанной на теме WordPress, использование REST API плагина формы во многих случаях может иметь смысл. Например, если мы разрабатываем тему с использованием CSS-фреймворка, ориентированного на служебные программы, то оформление визуализированной формы с помощью фиксированной разметки, структурированной с использованием соглашения о классах, подобных БЭМ, оставляет неприятный привкус во рту любого разработчика.

Цель этой статьи – представить две конечные точки отправки плагинов форм WordPress и показать способ воссоздать типичное поведение, связанное с формами, которое мы привыкли выходить из коробки. Как правило, при отправке формы мы сталкиваемся с двумя основными проблемами. Первый – это отправка самих данных, а второй – предоставление пользователю содержательной обратной связи.

Итак, начнем с этого.

Конечные точки

Отправка данных – более простая часть. Обе конечные точки ожидают POSTзапроса, а динамическая часть URL-адреса – это идентификатор формы.

Контактная форма 7 REST API доступна сразу после активации плагина и выглядит так:

https://your-site.tld/wp-json/contact-form-7/v1/contact-forms/<FORM_ID>/feedback

Если мы работаем с Gravity Forms, конечная точка принимает такую ​​форму:

https://your-site.tld/wp-json/gf/v2/forms/<FORM_ID>/submissions

REST API Gravity Forms по умолчанию отключен. Чтобы включить его, мы должны перейти в настройки плагина, затем на страницу REST API и установить флажок «Разрешить доступ к API». Создавать ключ API нет необходимости, поскольку конечная точка отправки формы не требует этого.

Тело запроса

В нашем примере формы есть пять полей со следующими правилами:

  • обязательное текстовое поле
  • обязательное поле электронной почты
  • обязательное поле даты, которое принимает даты до 4 октября 1957 г.
  • необязательное текстовое поле
  • обязательный флажок

Пример отправка формы без с помощью WordPress REST API (2021)

Для bodyключей запроса Контактной формы 7 мы должны определить их с помощью синтаксиса тегов формы :

{ "somebodys-name": "Marian Kenney", "any-email": "marian2210@geocities.com", "before-space-age": "1922-03-11", "optional-message": "", "fake-terms": "1" }

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

Пример отправка формы без с помощью WordPress REST API (2021)

{ "input_1": "Marian Kenney", "input_2": "marian2210@geocities.com", "input_3": "1922-03-11", "input_4": "", "input_5_1": "1" }

Отправка данных

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

Собирая все вместе, мы получаем такую ​​HTML-структуру для Контактной формы 7:

<form action="https://your-site.tld/wp-json/contact-form-7/v1/contact-forms/<FORM_ID>/feedback" method="post"> <label for="somebodys-name">Somebody's name</label> <input id="somebodys-name" type="text" name="somebodys-name"> <!-- Other input elements --> <button type="submit">Submit</button> </form>

В случае гравитации форм, нам нужно только переключить actionи на nameатрибуты:

<form action="https://your-site.tld/wp-json/gf/v2/forms/<FORM_ID>/submissions" method="post"> <label for="input_1">Somebody's name</label> <input id="input_1" type="text" name="input_1"> <!-- Other input elements --> <button type="submit">Submit</button> </form>

Поскольку вся необходимая информация доступна в HTML, мы готовы отправить запрос. Один из способов сделать это – использовать FormDataв сочетании с fetch:

const formSubmissionHandler = (event) => { event.preventDefault(); const formElement = event.target, { action, method } = formElement, body = new FormData(formElement); fetch(action, { method, body }) .then((response) => response.json()) .then((response) => { // Determine if the submission is not valid if (isFormSubmissionError(response)) { // Handle the case when there are validation errors } // Handle the happy path }) .catch((error) => { // Handle the case when there's a problem with the request }); }; const formElement = document.querySelector("form"); formElement.addEventListener("submit", formSubmissionHandler);

Мы можем отправить заявку без особых усилий, но пользовательский опыт, мягко говоря, невысокий. Мы должны предоставить пользователям как можно больше рекомендаций для успешной отправки формы. По крайней мере, это означает, что нам необходимо:

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

Проверка поля

Помимо использования встроенной проверки HTML-формы, мы можем использовать JavaScript для дополнительной проверки на стороне клиента и / или воспользоваться преимуществами проверки на стороне сервера.

Когда дело доходит до проверки на стороне сервера, как Contact Form 7, так и Gravity Forms предлагают это прямо из коробки и возвращают сообщения об ошибках проверки как часть ответа. Это удобно, поскольку мы можем контролировать правила проверки из администратора WordPress.

Для более сложных правил проверки, таких как проверка условного поля, может иметь смысл полагаться только на серверную часть, потому что синхронизация внешней проверки JavaScript с настройками плагинов может стать проблемой обслуживания.

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

Ответные сообщения

Ответ при ошибке проверки для контактной формы 7 выглядит следующим образом:

{ "into": "#", "status": "validation_failed", "message": "One or more fields have an error. Please check and try again.", "posted_data_hash": "", "invalid_fields": [ { "into": "span.wpcf7-form-control-wrap.somebodys-name", "message": "The field is required.", "idref": null, "error_id": "-ve-somebodys-name" }, { "into": "span.wpcf7-form-control-wrap.any-email", "message": "The field is required.", "idref": null, "error_id": "-ve-any-email" }, { "into": "span.wpcf7-form-control-wrap.before-space-age", "message": "The field is required.", "idref": null, "error_id": "-ve-before-space-age" }, { "into": "span.wpcf7-form-control-wrap.fake-terms", "message": "You must accept the terms and conditions before sending your message.", "idref": null, "error_id": "-ve-fake-terms" } ] }

При успешной отправке ответ будет выглядеть так:

{ "into": "#", "status": "mail_sent", "message": "Thank you for your message. It has been sent.", "posted_data_hash": "d52f9f9de995287195409fe6dcde0c50" }

По сравнению с этим ответ на ошибку валидации Gravity Forms более компактен:

{ "is_valid": false, "validation_messages": { "1": "This field is required.", "2": "This field is required.", "3": "This field is required.", "5": "This field is required." }, "page_number": 1, "source_page_number": 1 }

Но ответ на успешную отправку больше:

{ "is_valid": true, "page_number": 0, "source_page_number": 1, "confirmation_message": "<div id='gform_confirmation_wrapper_1' class='gform_confirmation_wrapper '><div id='gform_confirmation_message_1' class='gform_confirmation_message_1 gform_confirmation_message'>Thanks for contacting us! We will get in touch with you shortly.</div></div>", "confirmation_type": "message" }

Хотя оба содержат нужную нам информацию, они не следуют общему соглашению, и у обоих есть свои причуды. Например, подтверждающее сообщение в Gravity Forms содержит HTML, а ключи сообщения проверки не имеют input_префикса – префикса, который требуется при отправке запроса. С другой стороны, ошибки проверки в контактной форме 7 содержат информацию, имеющую отношение только к их внешней реализации. Ключи полей нельзя использовать сразу; они должны быть извлечены.

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

{ "isSuccess": false, "message": "One or more fields have an error. Please check and try again.", "validationError": { "somebodys-name": "This field is required.", "any-email": "This field is required.", "input_3": "This field is required.", "input_5": "This field is required." } }

И об успешном представлении, мы бы установить, isSuccessчтобы trueи вернуть пустой объект ошибки проверки:

{ "isSuccess": true, "message": "Thanks for contacting us! We will get in touch with you shortly.", "validationError": {} }

Теперь нужно преобразовать то, что у нас есть, в то, что нам нужно. Код для нормализации ответа Contact Forms 7 следующий:

const normalizeContactForm7Response = (response) => { // The other possible statuses are different kind of errors const isSuccess = response.status === 'mail_sent'; // A message is provided for all statuses const message = response.message; const validationError = isSuccess? {}: // We transform an array of objects into an object Object.fromEntries( response.invalid_fields.map((error) => { // Extracts the part after "cf7-form-control-wrap" const key = /cf7[-a-z]*.(.*)/.exec(error.into)[1]; return [key, error.message]; }) ); return { isSuccess, message, validationError, }; };

Код для нормализации ответа Gravity Forms выглядит следующим образом:

const normalizeGravityFormsResponse = (response) => { // Provided already as a boolean in the response const isSuccess = response.is_valid; const message = isSuccess? // Comes wrapped in a HTML and we likely don't need that stripHtml(response.confirmation_message): // No general error message, so we set a fallback 'There was a problem with your submission.'; const validationError = isSuccess? {}: // We replace the keys with the prefixed version; // this way the request and response matches Object.fromEntries( Object.entries( response.validation_messages ).map(([key, value]) => [`input_${key}`, value]) ); return { isSuccess, message, validationError, }; };

У нас по-прежнему отсутствует способ отображения ошибок проверки, сообщений об успехе и переключаемых классов. Однако у нас есть удобный способ доступа к нужным нам данным, и мы удалили все несоответствия в ответах с помощью легкой абстракции. Собранный вместе, он готов к добавлению в существующую кодовую базу, или мы можем продолжить работу над ней.

[iframe src=”//codepen.io/anon/embed/MWbMMOr”]

Есть много способов решить оставшуюся часть. Что имеет смысл, будет зависеть от проекта. В ситуациях, когда нам в основном приходится реагировать на изменения состояния, нам может помочь декларативная и реактивная библиотека. Alpine.js был рассмотрен здесь на CSS-Tricks, и он идеально подходит как для демонстрации, так и для использования на производственных сайтах. Практически без каких-либо изменений мы можем повторно использовать код из предыдущего примера. Нам нужно только добавить правильные директивы и в нужных местах.

[iframe src=”//codepen.io/anon/embed/XWNLxpN”]

Подведение итогов

Соответствие интерфейсу интерфейса, которое предоставляют плагины форм WordPress, можно относительно легко выполнить для простых, простых форм – и таким образом, чтобы его можно было многократно использовать от проекта к проекту. Мы даже можем сделать это так, чтобы мы могли переключать плагин, не затрагивая интерфейс.

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

Использование WordPress в качестве автономной CMS для доступа к REST API плагина формы для достижения конечных точек отправки, несомненно, станет более широко используемой практикой. Это стоит изучить и помнить. В будущем я не удивлюсь, если увижу плагины форм WordPress, предназначенные в первую очередь для работы в таком контексте, как этот. Я могу представить себе плагин, в котором внешний рендеринг – это дополнительная функция, которая не является неотъемлемой частью его ядра. Какие последствия это имело бы, и если бы это могло иметь коммерческий успех, еще предстоит изучить, но это увлекательное пространство, чтобы наблюдать за его развитием.

Источник записи: css-tricks.com
Leave A Reply

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