Вопрос или проблема
Я пытаюсь обернуть ‘некоторые’ поля на странице оформления заказа в div и добавить несколько кнопок, потому что я реализую валидацию адреса.
В основном, на начальном этапе мне нужен обертка вокруг компании, адреса строки 1, адреса строки 2, города и почтового индекса, чтобы я мог их скрывать/показывать, но я не могу заставить это работать. Вот что я пробовал –
В моем файле фильтров:
function change_woocommerce_field_markup($field, $key, $args, $value){
if($key === 'billing_company') {
$field = '<div class="address-wrapper">'.$field;
}
else if ($key === 'billing_postcode') {
$field = $field.'</div>';
}
else {
$field = $field;
}
return $field;
}
add_filter('woocommerce_form_field', '\App\change_woocommerce_field_markup', 10, 4);
Таким образом, я добавляю и добавляю соответствующие поля с HTML, который открывает и закрывает обертку. Однако результирующий HTML выглядит так:
<div class="address-wrapper"></div>
<p class="form-row form-row-first validate-required" id="billing_first_name_field"....
<p class="form-row form-row-last validate-required" id="billing_last_name_field"....
Итак, он помещает обертку в верхнюю часть контейнера! Я не понимаю, что происходит?
Спасибо
Кевин
В вашем случае вам не нужно использовать фильтр для внедрения обертки. Просто переопределите файл шаблона оформления заказа и поставьте обертку в нужное вам место. В вашем вопросе вы хотите изменить форму выставления счета. Поэтому это должно быть из этого файла
woocommerce/templates/checkout/form-billing.php
. Вы можете вставить свою обертку в эту строку.
Если вы не знаете, как переопределять шаблон WooCommerce. Пожалуйста, посетите эту ссылку: https://docs.woocommerce.com/document/template-structure/
ОБНОВЛЕНИЕ: пример кода.
foreach ( $fields as $key => $field ) {
$field['return'] = true;
$before = "";
$after = "";
switch ($key) {
case 'billing_company':
$before="<div class="address-wrapper">";
break;
case 'billing_postcode':
$after="</div>";
break;
default:
# код...
break;
}
echo $before . woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ) . $after;
}
Я использую Bootstrap 4.x. Поэтому я тоже хотел изменить структуру. Вот что я сделал:
В woocommerce/templates/checkout/form-billing.php
я могу нацелиться на все поля отдельно, вызывая:
<div class="row">
<div class="col-6">
<?php woocommerce_form_field('billing_first_name', array('placeholder' => 'Имя *', 'required' => true), $checkout->get_value('billing_first_name')); ?>
</div>
<div class="col-6">
<?php woocommerce_form_field('billing_last_name', array('placeholder' => 'Фамилия *', 'required' => true), $checkout->get_value('billing_last_name')); ?>
</div>
</div>
Вывод вставляется внутри <p class="form-row form-row-first validate-required" id="billing_<имя-поля>_field">
, потому что он предопределен в: plugins/woocommerce/includes/wc-template-functions.php на строке 2692. Так что нет способа изменить это, потому что это жестко задано в функции шаблона. Вы можете написать свое собственное поле формы в обычном HTML, проверьте HTML-вывод woocommerce_form_field();
@the_lar: Спасибо за вашу информацию: Спасибо за указание на проблему с полем страны, я столкнулся с этим раздражающим багом. Если вы посмотрите файл, на строке 141 есть следующий код: rows.detach().appendTo( wrapper );
. Если вы посмотрите строку 114, вы увидите, что rows указывает на .form-row, что жестко задано в wc-template-functions.php.
Ответ или решение
Изменение HTML на странице оформления заказа в WooCommerce: Полное руководство
Вам нужно обернуть несколько полей на странице оформления заказа в индивидуальный контейнер и добавить некоторые кнопки для осуществления валидации адреса. В этом руководстве мы рассмотрим оптимальные способы достижения желаемого результата, включая использование фильтров и переопределение шаблонов.
1. Проблема с использованием фильтров
Вы уже пытались использовать фильтр woocommerce_form_field
, но, судя по вашему описанию, вы получили неожиданный результат. Ваша цель заключается в том, чтобы поместить контейнер <div class="address-wrapper">
для полей billing_company
, billing_address_1
, billing_address_2
, billing_city
и billing_postcode
.
Ваш исходный код:
function change_woocommerce_field_markup($field, $key, $args, $value){
if($key === 'billing_company') {
$field = '<div class="address-wrapper">'.$field;
}
else if ($key === 'billing_postcode') {
$field = $field.'</div>';
}
return $field;
}
add_filter('woocommerce_form_field', 'change_woocommerce_field_markup', 10, 4);
Как вы заметили, обертка появляется в верхней части контейнера, потому что она добавляется в момент, когда фильтр обрабатывает только отдельные поля. Это значит, что WooCommerce фактически обрабатывает каждый элемент по отдельности, и вам необходимо контролировать порядок вывода элементов.
2. Переопределение шаблона
С точки зрения более чистого решения, лучше переопределить шаблон, который отвечает за вывод полей оформления заказа. Вам необходимо скопировать файл woocommerce/templates/checkout/form-billing.php
в вашу тему (например, в yourtheme/woocommerce/checkout/form-billing.php
) и вносить изменения именно там.
Вот пример, как можно сгруппировать ваши поля в нужный контейнер:
<div class="address-wrapper">
<?php
woocommerce_form_field('billing_company', $fields['billing_company'], $checkout->get_value('billing_company'));
woocommerce_form_field('billing_address_1', $fields['billing_address_1'], $checkout->get_value('billing_address_1'));
woocommerce_form_field('billing_address_2', $fields['billing_address_2'], $checkout->get_value('billing_address_2'));
woocommerce_form_field('billing_city', $fields['billing_city'], $checkout->get_value('billing_city'));
woocommerce_form_field('billing_postcode', $fields['billing_postcode'], $checkout->get_value('billing_postcode'));
?>
</div>
Таким образом, вы сможете обернуть нужные поля в контейнер и управлять ими по своему усмотрению.
3. Структура с Bootstrap 4.x
Если вы используете Bootstrap, вы можете адаптировать вывод полей для лучшего отображения. Вот пример, как это может выглядеть:
<div class="row address-wrapper">
<div class="col-6">
<?php woocommerce_form_field('billing_company', array('placeholder' => 'Компания', 'required' => false), $checkout->get_value('billing_company')); ?>
</div>
<div class="col-6">
<?php woocommerce_form_field('billing_address_1', array('placeholder' => 'Адрес 1', 'required' => true), $checkout->get_value('billing_address_1')); ?>
</div>
<div class="col-6">
<?php woocommerce_form_field('billing_address_2', array('placeholder' => 'Адрес 2'), $checkout->get_value('billing_address_2')); ?>
</div>
<div class="col-6">
<?php woocommerce_form_field('billing_city', array('placeholder' => 'Город', 'required' => true), $checkout->get_value('billing_city')); ?>
</div>
<div class="col-6">
<?php woocommerce_form_field('billing_postcode', array('placeholder' => 'Почтовый индекс', 'required' => true), $checkout->get_value('billing_postcode')); ?>
</div>
</div>
Эта структура не только упрощает управление полями, но и обеспечивает правильное отображение в стиле Bootstrap.
Заключение
Использование фильтров в WooCommerce может быть полезно, однако в данном случае более целесообразно внести изменения непосредственно в шаблон. Убедитесь, что вы правильно понимаете структуру шаблонов WooCommerce для максимально эффективной адаптации.
Если у вас возникнут дополнительные вопросы по данной теме, не стесняйтесь задавать их.