Добро пожаловать в подробнейший пошаговый гайд, где я не только расскажу вам, как добавлять собственные поля на страницу оформления заказа, но также и как отобразить их значения в админке, письмах пользователю и администратору и на странице «Заказ принят».
Также хочу напомнить, что в моём видеокурсе по WooCommerce есть отдельный урок посвящённый кастомизации страници оформления заказа. Вот ссылка на него.
WooCommerce позволяет нам добавлять поля в разные места формы оформления заказа. Для каждой локации предусмотрен отдельный хук.
Хук | Расположение |
---|---|
woocommerce_before_checkout_billing_form | Перед полями платёжного адреса. |
woocommerce_after_checkout_billing_form | После полей платёжного адреса |
woocommerce_before_checkout_registration_form | Перед формы регистрации. |
woocommerce_after_checkout_registration_form | После формы регистрации. |
woocommerce_before_checkout_shipping_form | Перед полями адреса доставки. |
woocommerce_after_checkout_shipping_form | После полей адреса доставки. |
woocommerce_before_order_notes | Перед полем примечания к заказу. |
woocommerce_after_order_notes | После поля примечания к заказу. |
Кстати, по хукам страницы оформления заказа у меня на сайте есть отдельное руководство.
Предположим, что вы хотите добавить что-либо перед полем примечания к заказу, тогда это можно сделать так:
add_action( 'woocommerce_before_order_notes', 'true_custom_checkout_field' ); function true_custom_checkout_field() { echo 'Однажды тут будет поле.'; }
Не знаете, куда вставлять код?
Работает:
А теперь поменяем этот текст на настоящее поле. Это можно сделать функцией woocommerce_form_field().
add_action( 'woocommerce_before_order_notes', 'true_custom_checkout_field' ); function true_custom_checkout_field() { // выводим поле функцией woocommerce_form_field() woocommerce_form_field( 'billing_contactmethod', array( 'type' => 'select', // text, textarea, select, radio, checkbox, password 'required' => true, // по сути только добавляет значок "*" и всё 'class' => array( 'true-field', 'form-row-wide' ), // массив классов поля 'label' => 'Предпочитаемый метод связи', 'label_class' => 'true-label', // класс лейбла 'options' => array( // options for or '' => 'Выберите', // пустое значение 'По телефону' => 'По телефону', // 'значение' => 'заголовок' 'По email' => 'По email' ) ), $checkout->get_value( 'contactmethod' ) ); }
Не знаете, куда вставлять код?
Подробное описание всех параметров – в уроке про функцию woocommerce_form_field().
А вот результат:
Но что делать, если вам нужно добавить поле ну прямо обязательно после полей «Имя» и «Фамилия» и других вариантов нет?
Тут для нас также целых три хука на выбор.
Хук | Описание |
---|---|
woocommerce_default_address_fields | Позволяет добавить поле в обе группы полей одновременно – платёжного адреса и адреса доставки. |
woocommerce_billing_fields | Позволяет добавить поле в группу полей платёжного адреса. |
woocommerce_shipping_fields | Позволяет добавить поле в группу полей адреса доставки. |
Пробуем.
add_filter( 'woocommerce_billing_fields', 'true_add_custom_billing_field', 25 ); function true_add_custom_billing_field( $fields ) { // массив нового поля $new_field = array( 'billing_contactmethod' => array( 'type' => 'select', // text, textarea, select, radio, checkbox, password 'required' => true, // по сути только добавляет значок "*" и всё 'class' => array( 'true-field', 'form-row-wide' ), // массив классов поля 'label' => 'Предпочитаемый метод связи', 'label_class' => 'true-label', // класс лейбла 'options' => array( // options for or '' => 'Выберите', // пустое значение 'По телефону' => 'По телефону', // 'значение'=>'заголовок' 'По email' => 'По email' ) ) ); // объединяем поля $fields = array_slice( $fields, 0, 2, true ) + $new_field + array_slice( $fields, 2, NULL, true ); return $fields; }
Всё ещё не знаете, куда вставлять код?
Все параметры массива $new_field
идентичны параметрам функции woocommerce_form_field(), которую мы использовали в предыдущем примере.
Результат:
То есть по сути у нас получается примерно то же самое, что было в предыдущем примере, только теперь мы смогли разместить наше поле совсем в другом месте.
И ещё одно но – при таком методе добавления полей они у нас будут появляться не только на странице оформления заказа, но и в личном кабинете, в секции адресов. Чтобы избежать этого, достаточно добавить условие на функцию is_checkout():
if( ! is_checkout() ) { return $fields; }
Как вы помните из предыдущей главы, рядом с полем мы добавили знак *
, типо как оно обязательное. Но не спешите радоваться. Попробуйте оформить заказ, не заполняя это поле. Небольшой спойлер – для первого метода никакой валидации там не будет, а для второго – отобразится стандартное сообщение об ошибке!
Как же мы поступим?
Ну во-первых, про валидацию полей у меня на сайте уже был отдельный урок. Исходя из урока, всё, что нам потребуется – это хук woocommerce_after_checkout_validation
и проверка на то, что значение поля не пустое.
add_action( 'woocommerce_after_checkout_validation', 'truemisha_validate_field', 25, 2 ); function truemisha_validate_field( $fields, $errors ){ // проверка, что пустое if ( '' === $fields[ 'billing_contactmethod' ] ){ // удаление стандартной ошибки нужно, если вы решили использовать 2-й метод добавления поля $errors->remove( 'billing_contactmethod_required' ); // добавляем кастомную ошибку $errors->add( 'validation', 'А вы забыли указать предпочтительный метод связи с вами!' ); } }
Результат:
Тут всё очень похоже на обычный хук save_post
, если вы с ним работали до этого. Проверяем, что поле заполнено и сохраняем его в метаданные заказа функцией update_post_meta()
. Ведь заказы – это типы постов.
add_action( 'woocommerce_checkout_update_order_meta', 'true_save_field', 25 ); function true_save_field( $order_id ){ if( ! empty( $_POST[ 'billing_contactmethod' ] ) ) { update_post_meta( $order_id, 'billing_contactmethod', sanitize_text_field( $_POST[ 'billing_contactmethod' ] ) ); } }
Если в админке WooCommerce вы перейдёте в редактирование заказа, то там будет большой метабокс с информацией о заказе – «Детали заказа». Давайте для начала выведем там значение нашего поля, а потом ещё и добавим в него возможность редактирования.
Прежде всего WooCommerce нам даёт неплохой выбор относительно того, где мы будем выводить информацию, это можно понять по целым трём доступным хукам.
woocommerce_admin_order_data_after_order_details
– если вы хотите добавить информацию в первую колонку, под полем «Клиент».woocommerce_admin_order_data_after_billing_address
– под платёжным адресом.woocommerce_admin_order_data_after_shipping_address
– под адресом доставки.В целом я думаю для нас довольно логичным решение будет использовать второй хук. Тогда:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'true_print_field_value', 25 ); function true_print_field_value( $order ) { if( $method = get_post_meta( $order->get_id(), 'billing_contactmethod', true ) ) { echo '<p><strong>Предпочтительный метод связи:</strong><br>' . esc_html( $method ) . '</p>'; } }
В итоге вставляем этот код, куда нужно и получаем:
Самое интересное начинается, когда мы хотим добавить возможность редактирования этой опции прямо из деталей заказа. Но на самом деле ничего сложного нет.
add_action( 'woocommerce_admin_order_data_after_billing_address', 'true_print_editable_field_value', 25 ); function true_print_editable_field_value( $order ){ $method = get_post_meta( $order->get_id(), 'billing_contactmethod', true ); echo '<div class="address"> <p' . ( ! $method ? ' class="none_set"' : '' ) . '> <strong>Предпочтительный метод связи:</strong> ' . ( $method ? $method : 'Не указан.' ) . ' </p> </div> <div class="edit_address">'; woocommerce_wp_select( array( 'id' => 'billing_contactmethod', 'label' => 'Предпочтительный метод связи:', 'wrapper_class' => 'form-field-wide', 'value' => $method, 'options' => array( 'По телефону' => 'По телефону', // 'значение'=>'заголовок' 'По email' => 'По email' ) ) ); echo '</div>'; } // и сохраняем add_action( 'woocommerce_process_shop_order_meta', 'true_save_billing_details' ); function true_save_billing_details( $order_id ){ update_post_meta( $order_id, 'billing_contactmethod', wc_clean( $_POST[ 'billing_contactmethod' ] ) ); }
У меня на сайте вы можете почитать про функции woocommerce_wp_text_input(), woocommerce_wp_textarea_input(), woocommerce_wp_select(), woocommerce_wp_radio() и woocommerce_wp_checkbox().
После вставки этого кода вы сможете редактировать значение данного поля при клике на иконку карандашика.
О том, как добавлять строки в таблицы в email-письмах, у меня тоже есть отдельный урок на сайте. Поэтому, если вдруг вам захочется более детально в этом разобраться, то вэлкам.
А сейчас готовый код по добавлению нашего поля!
Код применится как к письму администратору магазина, так и к письму клиенту.
add_filter( 'woocommerce_get_order_item_totals', 'truemisha_field_in_email', 25, 2 ); function truemisha_field_in_email( $rows, $order ) { // удалите это условие, если хотите добавить значение поля и на страницу "Заказ принят" if( is_order_received_page() ) { return $rows; } $rows[ 'billing_contactmethod' ] = array( 'label' => 'Предпочитаемый метод связи', 'value' => get_post_meta( $order->get_id(), 'billing_contactmethod', true ) ); return $rows; }
В результате всё получилось:
Понравился урок? Тогда предлагаю вам продолжить прокачивать свои навыки по WooCommerce в моём видеокурсе :)
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Добрый день. Как в Value поля предварительно внести данные из Профиля Пользователя?
Создал дополнительное поле в Профиле "Номер бонусной карты" и мне нужно, чтобы в заказе изначально поле было введено на странице оформления заказа, а ели вдруг оно пустое, то после заполнения пользователем информация обновлялась в Профиле Пользователя. Попробовал следующий вариант кода, но не выходит.
Большое спасибо тебе за урок! Очень полезно!)
Может это только у меня возникли проблемы с ним, но всё же, на всякий случай, скажу -
В пункте 1.1 при попытке вывести новое поле, код не работал до тех пор, пока во второй строчке не добавить ($checkout). Не
а
Спасибо тебе и всего хорошего!)