如何连接WooCommerce收银台?

时间:2018-07-27 作者:AmintaCode

默认Woocommerce表单签出的每个字段都有以下标记:

<p class="form-row form-row-first validate-required" id="billing_first_name_field" data-priority="10">
     <label for="billing_first_name" class="">Name&nbsp;
           <abbr class="required" title="required">*</abbr>
     </label>
     <span class="woocommerce-input-wrapper">
          <input type="text" class="input-text " name="billing_first_name" id="billing_first_name" placeholder="" value="" autocomplete="given-name">
     </span>
</p>
现在,我想:

在包装器中包装每个字段,如<div class="single-field-wrapper"><p [...] </div>将前两个字段“billing\\u first\\u name”和“billing\\u last\\u name”包装在类似<div class="first-and-second-field-wrapper"> [...] </div>function woocommerce_form_field( $key, $args, $value = null ) 打电话进来form-billing.php 模板如下:

<?php
        $fields = $checkout->get_checkout_fields( \'billing\' );

        foreach ( $fields as $key => $field ) {
            if ( isset( $field[\'country_field\'], $fields[ $field[\'country_field\'] ] ) ) {
                $field[\'country\'] = $checkout->get_value( $field[\'country_field\'] );
            }
            woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
        }
    ?>
所以在functions.php 我写道:

function change_woocommerce_field_markup($field, $key, $args, $value){

  $field = \'<div class="single-field-wrapper">\'.$field.\'</div>\';

  if($key === \'billing_first_name\') {

      $field = \'<div class="first-and-second-field-wrapper">\'.$field;
   }
  else if ($key === \'billing_last_name\') {

      $field = $field.\'</div>\';
   }

   else {
      $field = $field;
   }

    return $field;
   } 

  add_filter("woocommerce_form_field","change_woocommerce_field_markup", 10, 4);
意外地,我得到了以下标记:

<div class="first-and-second-field-wrapper">
       <div class="single-field-wrapper">
            <div class="single-field-wrapper">
            [here there are all the fields, one under the other ]
            </div>
       <div class="single-field-wrapper"></div> 
       <div class="single-field-wrapper"></div> 
       <div class="single-field-wrapper"></div> 
       <div class="single-field-wrapper"></div> 
       <div class="single-field-wrapper"></div>   
       <div class="single-field-wrapper"></div> 
       <div class="single-field-wrapper"></div> 
       <div class="single-field-wrapper"></div> 
 </div>
任何人都能解释为什么会有这种意想不到的行为?

2 个回复
最合适的回答,由SO网友:nmr 整理而成

没有挂钩woocommerce_form_field, 有钩子woocommerce_form_field_{$args[type]} (doc).

$args[type] 可以(看here 对于可用选项):

文本,复选框,国家,国家billing\\u first\\u name”和“billing\\u last\\u name”字段包装为<div class="first-and-second-field-wrapper"> [...] </div>.

function change_woocommerce_field_markup($field, $key, $args, $value) {

   $field = \'<div class="single-field-wrapper">\'.$field.\'</div>\';

   if($key === \'billing_first_name\')
      $field = \'<div class="first-and-second-field-wrapper">\'.$field;
   else if ($key === \'billing_last_name\')
      $field = $field.\'</div>\';

    return $field;
} 

add_filter("woocommerce_form_field_text","change_woocommerce_field_markup", 10, 4);
它还将包装text 使用键入字段<div class="single-field-wrapper">...</div>.
BUT
某些具有自己类型(如state或email)的文本字段需要其他挂钩,例如:

add_filter("woocommerce_form_field_country","change_woocommerce_field_markup", 10, 4);
add_filter("woocommerce_form_field_email","change_woocommerce_field_markup", 10, 4);
<小时>UPDATE #1

上述代码在WC-v3.3.7中工作。

在WC-v3.4中。xx您可以得到:

<div class="first-and-second-field-wrapper">
    <div class="single-field-wrapper">
        <div class="single-field-wrapper">
            [here there are all the fields, one under the other ]
        </div>
    <div class="single-field-wrapper"></div> 
    <div class="single-field-wrapper"></div> 
    <div class="single-field-wrapper"></div> 
    ....
    <div class="single-field-wrapper"></div>
</div>
因为javascript对表单行进行排序.woocommerce-billing-fields__field-wrapper. 查看文件woocommerce/assets/js/frontend/address-i18n.js, 来自第99行first 项目(用类标记.form-row), 按优先级排序项目并将其插入previously selected parent element.

对于测试,更改文件address-i18.js, 第99行
var fieldsets = $(\'.woocommerce-billing-fields__field-wrapper, ...

var fieldsets = $(\'.woocommerce-billing-fields__field-wrapper2, ...
并上载为address-i18.min.js.

Removing JS sorting is not a solution, it is just a test. 不按JS排序,您将得到以下结果:

<div class="first-and-second-field-wrapper">
    <div class="single-field-wrapper">
        <p class="form-row ..." id="billing_first_name_field"> <label for="billing_first_name"> ... </p>
    </div>
    <div class="single-field-wrapper">
        <p class="form-row ..." id="billing_last_name_field"> <label for="billing_last_name">... </p>
    </div>
</div>
<div class="single-field-wrapper">
   <p class="form-row ..." id="billing_company_field"> <label for="billing_company">...  </p>
</div>

SO网友:indextwo

我只是遇到了我以前没有发现的完全相同的问题。我最初打开this ticket on the WC GitHub 早在2015年,他们就添加了过滤器,这太棒了。。。但基于JS的重组令人痛苦。然而nmr\'s answer 为我指明了正确的方向:

随着JS重组在.form-row 元素,只需a)将其从要包装的字段中删除,b)将其添加到您自己的新字段包装器中:

function change_woocommerce_field_markup( $field, $key, $args, $value ) {

    //  Remove the .form-row class from the current field wrapper

    $field = str_replace(\'form-row\', \'\', $field);

    //  Wrap the field (and its wrapper) in a new custom div, adding .form-row so the reshuffling works as expected, and adding the field priority

    $field = \'<div class="form-row single-field-wrapper" data-priority="\' . $args[\'priority\'] . \'">\' . $field . \'</div>\';

    return $field;
}

add_filter( \'woocommerce_form_field\', \'change_woocommerce_field_markup\', 10, 4 );

结束

相关推荐