您的购物车目前是空的!
作者: wang
-
小狮网AI学习
通过修改核心文件实现(仅供学习和理解)
以下步骤将直接修改 WooCommerce 的模板文件。请务必在操作前备份你的网站和数据库。
第一步:定位并复制模板文件
WooCommerce 的结账页面字段是通过模板文件生成的。你需要找到并修改这个文件。
- 登录你的网站服务器(通过 FTP 或主机面板的文件管理器)。
- 导航到以下目录:
wp-content/plugins/woocommerce/templates/checkout/ - 找到名为
form-billing.php的文件。这个文件负责生成账单地址区域的所有字段,包括姓名。 - 将
form-billing.php文件复制到你的电脑上,作为备份和编辑用。
第二步:编辑
form-billing.php文件用代码编辑器(如 VS Code, Sublime Text 等)打开你复制的
form-billing.php文件。- 找到姓氏和名字的代码块:
在文件中搜索
$fields['billing']['billing_first_name']和$fields['billing']['billing_last_name']。你会找到类似下面这样的代码块:php
<p class="form-row form-row-first validate-required" id="billing_first_name_field"> <label for="billing_first_name" class=""> <?php esc_html_e( 'First name', 'woocommerce' ); ?> <span class="required">*</span> </label> <input type="text" class="input-text" name="billing_first_name" id="billing_first_name" autocomplete="given-name" value="<?php echo esc_attr( $checkout->get_value( 'billing_first_name' ) ); ?>" placeholder="<?php esc_attr_e( 'First name', 'woocommerce' ); ?>"> </p> <p class="form-row form-row-last validate-required" id="billing_last_name_field"> <label for="billing_last_name" class=""> <?php esc_html_e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span> </label> <input type="text" class="input-text" name="billing_last_name" id="billing_last_name" autocomplete="family-name" value="<?php echo esc_attr( $checkout->get_value( 'billing_last_name' ) ); ?>" placeholder="<?php esc_attr_e( 'Last name', 'woocommerce' ); ?>"> </p>删除原有代码并替换为新代码:
将上面找到的两个
<p>...</p>代码块完全删除,然后将其替换为下面的代码:php
<?php // 获取已保存的姓名值,如果存在则合并显示 $full_name = ''; $first_name = $checkout->get_value( 'billing_first_name' ); $last_name = $checkout->get_value( 'billing_last_name' ); if ( ! empty( $first_name ) && ! empty( $last_name ) ) { $full_name = $first_name . ' ' . $last_name; } elseif ( ! empty( $first_name ) ) { $full_name = $first_name; } elseif ( ! empty( $last_name ) ) { $full_name = $last_name; } ?> <p class="form-row form-row-wide validate-required" id="billing_full_name_field"> <label for="billing_full_name" class=""> <?php esc_html_e( 'Full Name', 'woocommerce' ); ?> <span class="required">*</span> </label> <input type="text" class="input-text" name="billing_full_name" id="billing_full_name" value="<?php echo esc_attr( $full_name ); ?>" placeholder="<?php esc_attr_e( 'Enter your full name', 'woocommerce' ); ?>"> </p>代码解释:- 我们先用 PHP 逻辑获取了
billing_first_name和billing_last_name的值,并将它们合并成一个$full_name变量。这样,如果用户之前填写过信息,表单会自动显示他们的全名。 - 然后,我们创建了一个新的、宽度为
form-row-wide(整行)的输入框。 - 这个新输入框的
name属性是billing_full_name,我们将在下一步用它来处理数据。
- 我们先用 PHP 逻辑获取了
第三步:处理表单提交的数据
现在,前端的输入框合并好了,但当用户提交表单时,WooCommerce 仍然期望收到
billing_first_name和billing_last_name两个字段。我们需要一个机制,将用户在billing_full_name输入框中填写的内容,分割成名和姓,并分别存入对应的数据库字段。这需要修改另一个核心文件。
- 回到服务器上的 WooCommerce 插件目录:
wp-content/plugins/woocommerce/导航到
includes/class-wc-checkout.php文件。这个文件是处理结账流程的核心类。备份此文件! 这个文件非常重要。
打开
class-wc-checkout.php并找到process_checkout()方法。这个方法非常长。在
process_checkout()方法内部,找到处理$_POST数据的地方。通常在方法的开头部分,你会看到类似$posted_data = $this->get_posted_data();的代码。在
$posted_data = $this->get_posted_data();之后,添加以下代码:php
// Custom code to split full name into first and last name if ( isset( $_POST['billing_full_name'] ) && ! empty( $_POST['billing_full_name'] ) ) { $full_name = sanitize_text_field( $_POST['billing_full_name'] ); // Split the name into parts. This will split on the last space. $name_parts = preg_split( '/\s+(?=\S*+$)/', $full_name ); if ( ! empty( $name_parts ) ) { $first_name = $name_parts[0]; $last_name = isset( $name_parts[1] ) ? $name_parts[1] : ''; // Update the posted data so WooCommerce uses our split values $_POST['billing_first_name'] = $first_name; $_POST['billing_last_name'] = $last_name; // Also update the $posted_data array in case it's used later $posted_data['billing_first_name'] = $first_name; $posted_data['billing_last_name'] = $last_name; } }代码解释:- 我们首先检查
billing_full_name是否存在于提交的数据中。 - 使用正则表达式
preg_split( '/\s+(?=\S*+$)/', $full_name )来分割字符串。这个正则表达式会在最后一个空格处分割,这样可以正确处理中间有空格的名字(例如 “Van der Sar” 会被当作姓)。 - 然后,我们将分割后的第一部分作为
billing_first_name,剩余部分(如果有)作为billing_last_name。 - 最后,我们手动更新了
$_POST全局变量和$posted_data数组,将分割好的名和姓放回去。这样,后续的 WooCommerce 处理流程就会无缝地接收到它所期望的数据格式。
- 我们首先检查
第四步:上传修改后的文件
- 将你修改过的
form-billing.php文件上传回服务器的wp-content/plugins/woocommerce/templates/checkout/目录,覆盖原始文件。 - 将你修改过的
class-wc-checkout.php文件上传回服务器的wp-content/plugins/woocommerce/includes/目录,覆盖原始文件。
完成以上步骤后,刷新你的结账页面,你应该就能看到合并后的 “姓名” 输入框了。提交订单后,你可以在 WordPress 后台的订单详情中检查,姓名是否被正确地分割并保存。
✅ 安全、推荐的实现方法(自定义插件)
为了让你的修改永久生效,我们应该使用 WooCommerce 提供的钩子(Hooks)系统。下面是创建一个简单自定义插件的完整代码。
- 在
wp-content/plugins/目录下,创建一个新文件夹,命名为wc-merge-name-fields。 - 在该文件夹内,创建一个新文件,命名为
wc-merge-name-fields.php。 - 将以下代码完整地复制并粘贴到
wc-merge-name-fields.php文件中:
php
<?php /* Plugin Name: WooCommerce Merge Name Fields Plugin URI: https://yourwebsite.com/ Description: Merges the first and last name fields into a single full name field on the WooCommerce checkout page. Version: 1.0 Author: Your Name Author URI: https://yourwebsite.com/ License: GPL2 */ // Exit if accessed directly if ( ! defined( 'ABSPATH' ) ) { exit; } // Check if WooCommerce is active if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { /** * Step 1: Remove the default first and last name fields */ function wc_remove_default_name_fields( $fields ) { unset( $fields['billing']['billing_first_name'] ); unset( $fields['billing']['billing_last_name'] ); return $fields; } add_filter( 'woocommerce_billing_fields', 'wc_remove_default_name_fields' ); /** * Step 2: Add the custom full name field */ function wc_add_custom_full_name_field( $fields ) { $fields['billing']['billing_full_name'] = array( 'label' => __( 'Full Name', 'woocommerce' ), 'placeholder' => _x( 'Enter your full name', 'placeholder', 'woocommerce' ), 'required' => true, 'class' => array( 'form-row-wide' ), 'clear' => true, 'priority' => 20, // Position it where the original name fields were ); return $fields; } add_filter( 'woocommerce_billing_fields', 'wc_add_custom_full_name_field' ); /** * Step 3: Process the custom field data */ function wc_process_custom_name_field_data( $order_id, $posted_data, $order ) { if ( isset( $_POST['billing_full_name'] ) && ! empty( $_POST['billing_full_name'] ) ) { $full_name = sanitize_text_field( $_POST['billing_full_name'] ); // Split the name into parts (split on the last space) $name_parts = preg_split( '/\s+(?=\S*+$)/', $full_name ); if ( ! empty( $name_parts ) ) { $first_name = $name_parts[0]; $last_name = isset( $name_parts[1] ) ? $name_parts[1] : ''; // Update the order meta data update_post_meta( $order_id, '_billing_first_name', $first_name ); update_post_meta( $order_id, '_billing_last_name', $last_name ); // Also update the user meta if the user is logged in if ( get_current_user_id() ) { update_user_meta( get_current_user_id(), 'billing_first_name', $first_name ); update_user_meta( get_current_user_id(), 'billing_last_name', $last_name ); } } } } add_action( 'woocommerce_checkout_update_order_meta', 'wc_process_custom_name_field_data', 10, 3 ); /** * Step 4: Display the full name correctly in admin order details */ function wc_admin_order_display_full_name( $order ) { $first_name = get_post_meta( $order->get_id(), '_billing_first_name', true ); $last_name = get_post_meta( $order->get_id(), '_billing_last_name', true ); if ( $first_name || $last_name ) { echo '<p><strong>' . __( 'Billing Name:', 'woocommerce' ) . '</strong> ' . esc_html( $first_name . ' ' . $last_name ) . '</p>'; } } // Remove the default billing name display remove_action( 'woocommerce_admin_order_data_after_billing_address', 'woocommerce_admin_order_display_billing_address', 10 ); // Add our custom billing name display add_action( 'woocommerce_admin_order_data_after_billing_address', 'wc_admin_order_display_full_name', 10 ); }- 保存文件后,登录到你的 WordPress 后台,导航到 “插件” > “已安装插件”,你会看到 “WooCommerce Merge Name Fields” 这个新插件。点击 “启用” 即可。
现在,你的结账页面姓名输入框已经安全地合并了,并且这个修改不会因为 WooCommerce 的升级而丢失。这才是在 WordPress 生态中进行开发的正确方式。